Exécuter ou ignorer les tests sous condition dans JUnit 4

1. Vue d'ensemble

Imaginons que nous ayons un test pour du code qui dépend du système d'exploitation et qui ne devrait s'exécuter que si notre machine de test fonctionne sous Linux. S'il est exécuté sur un autre système d'exploitation, nous voulons que le test n'échoue pas, mais qu'il soit ignoré lors de l'exécution.

Une première approche pourrait être d'utiliser quelques instructions if pour vérifier cette condition à l'aide des propriétés de la classe System . Cela fonctionne, bien sûr, mais JUnit a une méthode plus propre et plus élégante.

Dans ce court tutoriel, nous allons voir comment nous pouvons exécuter ou ignorer conditionnellement des tests dans JUnit 4 à l'aide de la classe Assume .

2. La classe Assume

Cette classe fournit un ensemble de méthodes pour prendre en charge l'exécution de tests conditionnels en fonction de certaines conditions . Notre test ne fonctionnera que si toutes ces conditions sont remplies. Sinon, JUnit sautera simplement son exécution et le marquera comme réussi dans le rapport de test . Ce dernier est la principale différence avec la classe Assert , dans laquelle une condition d'échec conduit le test à se terminer comme un échec .

Une chose importante à noter est que le comportement que nous avons décrit pour la classe Assume est exclusif au runner JUnit par défaut . Avec les coureurs personnalisés, les choses peuvent être différentes.

Enfin, de la même manière qu'avec Assert , nous pouvons appeler les méthodes Assume soit dans les méthodes annotées @Before ou @BeforeClass , soit dans la méthode @Test elle-même.

Passons maintenant en revue les méthodes les plus utiles de la classe Assume en montrant quelques exemples. Pour tous les exemples suivants, supposons que getOsName () renvoie Linux.

2.1. Utilisation de assumeThat

La méthode assumeThat () vérifie que l'état - dans ce cas, getOsName () - satisfait aux conditions du matcher passé:

@Test public void whenAssumeThatAndOSIsLinux_thenRunTest() { assumeThat(getOsName(), is("Linux")); assertEquals("run", "RUN".toLowerCase()); }

Dans cet exemple, nous avons vérifié si getOsName () est égal à Linux . Comme getOsName () retourne Linux , le test sera exécuté . Notez que nous utilisons la méthode du matcher Hamcrest est (T) comme matcher ici.

2.2. Utilisation de assumeTrue

De même, nous pouvons utiliser la méthode assumeTrue () pour spécifier une expression booléenne qui doit être évaluée à true pour que le test s'exécute. S'il est évalué à faux , le test sera ignoré:

private boolean isExpectedOS(String osName) { return "Linux".equals(osName); } @Test public void whenAssumeTrueAndOSIsLinux_thenRunTest() { assumeTrue(isExpectedOS(getOsName())); assertEquals("run", "RUN".toLowerCase()); } 

Dans ce cas, isExpectedOs () renvoie true . Par conséquent, les conditions d'exécution du test ont été remplies et le test sera exécuté .

2.3. Utilisation de assumeFalse

Enfin, nous pouvons utiliser la méthode assumeFalse () opposée pour spécifier une expression booléenne qui doit être évaluée à false pour que le test s'exécute. S'il est évalué à vrai , le test sera ignoré:

@Test public void whenAssumeFalseAndOSIsLinux_thenIgnore() { assumeFalse(isExpectedOS(getOsName())); assertEquals("run", "RUN".toLowerCase()); }

Dans ce cas, comme isExpectedOs () renvoie également true, les conditions d'exécution du test ne sont pas remplies et le test sera ignoré .

2.4. Utilisation de assumeNotNull

Lorsque nous voulons ignorer un test si une expression est nulle, nous pouvons utiliser la méthode assumeNotNull () :

@Test public void whenAssumeNotNullAndNotNullOSVersion_thenRun() { assumeNotNull(getOsName()); assertEquals("run", "RUN".toLowerCase()); }

Comme getOsName () renvoie une valeur non nulle, la condition d'exécution du test est satisfaite et le test s'exécute.

2.5. Utilisation de assumeNoException

Enfin, nous pourrions vouloir ignorer un test si une exception est levée. Nous pouvons utiliser assumeNoException () à cette fin:

@Test public void whenAssumeNoExceptionAndExceptionThrown_thenIgnore() { assertEquals("everything ok", "EVERYTHING OK".toLowerCase()); String t=null; try { t.charAt(0); } catch(NullPointerException npe){ assumeNoException(npe); } assertEquals("run", "RUN".toLowerCase()); }

Dans cet exemple, comme t est nul, une exception NullPointerException est levée, par conséquent les conditions pour que le test s'exécute ne sont pas remplies et le test sera ignoré .

3. Où devrions-nous placer l' appel assumeXXX ?

Il est important de noter que le comportement des méthodes assumeXXX dépend de l'endroit où nous les mettons dans nos tests .

Modifions légèrement notre exemple supposThat pour que l' appel assertEquals () passe en premier. Aussi, faisons échouer assertEquals () :

@Test public void whenAssumeFalseAndOSIsLinux_thenIgnore() { assertEquals("run", "RUN"); assumeFalse(isExpectedOS(getOsName())); } 

Lorsque nous exécutons cet exemple, nous aurons:

org.junit.ComparisonFailure: Expected :run Actual :RUN

Dans ce cas, notre test n'est pas ignoré car il a échoué avant que nous ayons atteint l' appel à assumeThat () . La même chose se produit avec toutes les méthodes assumeXXX . Nous devons donc nous assurer de les mettre au bon endroit dans notre méthode de test .

4. Conclusion

Dans ce court didacticiel, nous avons vu comment nous pouvons décider conditionnellement si un test doit être exécuté ou non, en utilisant la classe Assume dans JUnit 4. Dans le cas où nous utilisons JUnit 5, il est également disponible en version 5.4 ou ultérieure .

Comme toujours, le code source des exemples que nous avons parcourus se trouve sur GitHub.