JenkinsPipelineUnit icon indicating copy to clipboard operation
JenkinsPipelineUnit copied to clipboard

How to simply test function args in a pipeline shared library ?

Open frederic-valin-maif opened this issue 3 years ago • 3 comments

Bonjour,

J'ai découvert ce framework récemment suite à la recherche de l'intégration de tests dans notre shared library.

N'étant pas très au fait des tests unitaires, j'avoue mon inexpérience pour les mettre en oeuvre et sollicite un peu d'aide.

Avant d'aller dans la mise en oeuvre de tests de non régression, je voulais implémenter une 1ère étape à savoir des tests sur des fonctions de la shared library pour tester que les paramètres en entrée/sortie n'ont pas été modifiés afin de garantir la rétro compatibilité.

Dans une classe de ma shared library j'ai par exemple, une méthode définie de la manière suivante :

class Arguments implements Serializable {
...
/**
     * Récupère la valeur d'un paramètre de ARGS_MAP
     * @param key (String) nom du paramètre
     * @return valeur du paramètre (String)
     */
    static String getParam(String key) {
   ...
   }
}

Et je voudrai juste vérifier que la fonction prend en entrée une String et renvoie une String, sans pour autant exécuter le pipeline.

J'ai donc créé une classe TestArguments de la manière suivante

class TestArguments extends BasePipelineTest {


    @Override
    @Before
    void setUp() throws Exception {
        scriptRoots += "src/fr/ingdev/arguments"
        super.setUp()
    }

    @Test
    void testArgumentsMethods() {
        loadScript('Arguments.groovy') // Chargement de la classe des Arguments avec toutes ses fonctions
        
        // Que faut-il faire ici ?
        // Utiliser la classe MethodCall ?
       // Créer un script jenkins pour déclencher l'appel de la méthode et vérifier dans la stack ?
        ....
    }
}

Merci pour votre aide.

frederic-valin-maif avatar Oct 25 '20 15:10 frederic-valin-maif

You can use something like the following snippet in the test method (note: I did not test this but it should work with minimal to no changes)

List expectedMethods = [
    [name: "getParam", returnType: "java.lang.String", args: ["java.lang.String"]],
    [name: "someOtherMethod", returnType: "java.lang.Object", args: ["java.lang.String", "java.lang.Map"]],
]

Script loadedScript = loadScript('Argument.groovy')

expectedMethods.each { expectedMethod ->
    assertTrue(
        loadedScript.getMetaClass().getMethods().any { method ->
            method.name == expectedMethod.name &&
            method.returnType.name == expectedMethod.returnType &&
            method.parameterTypes*.name == expectedMethod.args
        }
    )
}

mahmoud-ashi avatar Oct 30 '20 23:10 mahmoud-ashi

How would one actually execute the library functions (and be able to mock the Jenkins specific stuff like sh and readFile) without them having to be called from a Jenkinsfile or some global variable? I don't see any examples on how to do this. The section on testing shared libraries suggests to load the library in a Jenkisfile, and then call library functions from the Jenkinsfile. However this doesn't really resemble actual unit testing, since the library needs to be execute indirectly through a Jenkinsfile.

wheelerlaw avatar Nov 05 '20 17:11 wheelerlaw

take a look at this question https://github.com/jenkinsci/JenkinsPipelineUnit/issues/308.

mahmoud-ashi avatar Nov 07 '20 21:11 mahmoud-ashi