Utilisation de Jenkins avec un simple projet Java en local

L’objectif est de tester l’outil d’intégration Jenkins de manière très simple. Du coup, j’ai choisi de ne pas utiliser d’outils de gestion de code sources de type git, svn ou autre, mais juste de lancer un simple test en automatique.

Une autre contrainte a été d’utiliser Jenkins dans un conteneur Docker qui est démarré simplement via cette commande :

docker run --name=jenkins -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11

Le conteneur Jenkins est accessible via le navigateur sur l’URL http://127.0.0.1:8080/ avec les plugins recommandés.

Maintenant, on va fabriquer le code java basique qui ne fait que tester une fonction qui double un nombre passé en paramètre, voici le code :

public class Calcul {
	
	public static int doublement(int nombre) {
		return nombre * 2;
	}

}

Et le test avec Junit 5

class CalculTest {

	@Test
	void testDoublement() {		
		assertEquals(Calcul.doublement(0) , 0);
		assertEquals(Calcul.doublement(1) , 2);
	}

}

Le test est vraiment basic juste pour vérifier le fonctionnement. Maintenant pour tester en ligne de commande en pur Java (qui est aussi utiliser avec Jenkins d’ailleurs ), on peut utiliser cette outil de Junit en ligne de commande.

Télécharger le fichier junit-platform-console-standalone-1.8.2.jar de Console Launcher : https://junit.org/junit5/docs/snapshot/user-guide/#running-tests-console-launcher qui permet d’appeler l’outil de test Junit5 via une ligne de commande.

En local on peut donc lancer cette commande, par exemple dans le workspace:

java -jar c:\DEV20\eclipse-workspace-jee\JenkinsDemo\junit-platform-console-standalone-1.8.2.jar -cp c:\DEV20\eclipse-workspace-jee\JenkinsDemo\bin --scan-classpath  --disable-banner

Voici la sortie détaillée :

.
+-- JUnit Jupiter [OK]
| '-- CalculTest [OK]
|   '-- testDoublement() [OK]
'-- JUnit Vintage [OK]

Test run finished after 44 ms
[         3 containers found      ]
[         0 containers skipped    ]
[         3 containers started    ]
[         0 containers aborted    ]
[         3 containers successful ]
[         0 containers failed     ]
[         1 tests found           ]
[         0 tests skipped         ]
[         1 tests started         ]
[         0 tests aborted         ]
[         1 tests successful      ]
[         0 tests failed          ]

Ou la version avec erreur d’un test :

.
+-- JUnit Jupiter [OK]
| '-- CalculTest [OK]
|   '-- testDoublement() [X] expected: <2> but was: <1>
'-- JUnit Vintage [OK]

Failures (1):
  JUnit Jupiter:CalculTest:testDoublement()
    MethodSource [className = 'test.CalculTest', methodName = 'testDoublement', methodParameterTypes = '']
    => org.opentest4j.AssertionFailedError: expected: <2> but was: <1>
       org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
       org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
       org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:150)
       org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:145)
       org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:527)
       test.CalculTest.testDoublement(CalculTest.java:14)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
       java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       java.base/java.lang.reflect.Method.invoke(Method.java:568)
       [...]

Test run finished after 47 ms
[         3 containers found      ]
[         0 containers skipped    ]
[         3 containers started    ]
[         0 containers aborted    ]
[         3 containers successful ]
[         0 containers failed     ]
[         1 tests found           ]
[         0 tests skipped         ]
[         1 tests started         ]
[         0 tests aborted         ]
[         0 tests successful      ]
[         1 tests failed          ]

Pour disposer seulement de cette réponse en cas d’erreur, il faut ajouter le paramètre « –details=none » qui n’affichera qu’en cas d’erreur.

À présent, on peut copier tout le dossier du projet dans le conteneur Jenkins, car il n’a pas accès au dossier c:\DEV20\eclipse-workspace-jee\JenkinsDemo\ mais on aurait pu monter dans le conteneur Jenkins le dossier.

docker cp C:\DEV20\eclipse-workspace-jee\JenkinsDemo jenkins:/home

Donc l’ensemble des fichiers du projet et l’outil junit-platform-console-standalone-1.8.2.jar de Console Launcher se trouve dans le dossier /home/JenkinsDemo. On peut donc ensuite tester dans le conteneur comme ceci.

docker exec --user=root --workdir=/home/JenkinsDemo/ -it  jenkins  /bin/bash

On peut donc ensuite tester notre test dans le conteneur :

java -jar /home/JenkinsDemo/junit-platform-console-standalone-1.8.2.jar -cp /home/JenkinsDemo/bin/  --scan-classpath  --disable-banner --deta
ils=none

Passons maintenant dans Jenkins pour créer un job, « Construire un projet free-style » puis il faut utiliser le bouton « Avancé » pour avoir accès au dossier :

Puis, il faut indiquer le dossier de travail :

Maintenant, on va ajouter notre script comme critère de Build :

La commande testée précédemment doit être entrée pour valider le projet:

java -jar /home/JenkinsDemo/junit-platform-console-standalone-1.8.2.jar -cp /home/JenkinsDemo/bin/  --scan-classpath  --disable-banner --details=none

On peut ensuite sauvegarder les modifications et lancer ce job via « Lancer ce build » et on peut vérifier l’exécution dans le résultat de la console :

Cela permet de vérifier que les opérations s’exécutent correctement. A l’inverse voici une sortie de console en erreur après un échec du test :

Pour conclure et simplifié, on aurait pu monter le dossier du projet Eclipse directement dans le /home du conteneur avec cette commande :

docker run -it -v C:\DEV20\eclipse-workspace-jee\JenkinsDemo\:/home/JenkinsDemo/ --name=jenkins -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11

Le reste serait identique et grâce à Java portable entre Windows et Linux du conteneur, les commandes avec JUnit sont compatibles.

A propos Pierre Jean

Ingénieur de Recherche CERIS Centre d'Enseignement et de Recherche en Informatique et Systèmes IMT Mines Alès UMR Euromov DHM Plus de détails sur Pierre JEAN
Ce contenu a été publié dans Développement, IMT Mines Alès. Vous pouvez le mettre en favoris avec ce permalien.