Guide de JUnit 5

1. Vue d’ensemble

JUnit est l’un des frameworks de tests unitaires les plus populaires de l’écosystème Java. Bien que la version stable actuelle soit JUnit 4.12, une version 5.1.0 contient un certain nombre d’innovations intéressantes, avec l’objectif de prendre en charge les nouvelles fonctionnalités de Java 8 et versions ultérieures , ainsi que de permettre différents styles de test.

Cet article fait suite à notre lien:/junit-5-preview[aperçu de JUnit 5].

2. Dépendances Maven

Configurer JUnit 5.x.0 est assez simple, nous devons ajouter la dépendance suivante à notre pom. xml :

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.1.0</version>
    <scope>test</scope>
</dependency>

Il est important de noter que cette version nécessite Java 8 pour fonctionner .

De plus, il existe désormais un support direct pour exécuter des tests unitaires sur la plate-forme JUnit dans Eclipse ainsi qu’IntelliJ. Bien entendu, vous pouvez également exécuter des tests en utilisant l’objectif Maven Test.

Par ailleurs, IntelliJ prend en charge JUnit 5 par défaut. Par conséquent, exécuter JUnit 5 sur IntelliJ est assez simple, il suffit de cliquer avec le bouton droit de la souris → Exécuter ou de Ctrl-Maj-F10.

3. Architecture

JUnit 5 est composé de plusieurs modules différents issus de trois sous-projets différents:

3.1. JUnit Platform

La plate-forme est responsable du lancement des infrastructures de test sur la machine virtuelle Java.

Il définit une interface stable et puissante entre JUnit et son client, telle que des outils de construction.

L’objectif final est de faciliter l’intégration de ses clients à JUnit dans la découverte et l’exécution des tests.

Elle définit également l’API TestEngine pour le développement d’un cadre de test s’exécutant sur la plateforme JUnit.

Vous pouvez ainsi brancher des bibliothèques de test tierces directement dans JUnit en implémentant TestEngine personnalisé.

3.2. JUnit Jupiter

Ce module inclut de nouveaux modèles de programmation et d’extension permettant d’écrire des tests dans JUnit 5. Les nouvelles annotations par rapport à JUnit 4 sont les suivantes:

  • @ TestFactory - désigne une méthode qui est une fabrique de tests pour les dynamiques

tests ** @ DisplayName - définit un nom d’affichage personnalisé pour une classe de test ou un

méthode d’essai ** @ Nested - indique que la classe annotée est une classe imbriquée non statique

classe de test ** @ Tag - déclare les balises pour les tests de filtrage

  • @ ExtendWith - il est utilisé pour enregistrer des extensions personnalisées

  • @ BeforeEach – indique que la méthode annotée sera exécutée

avant chaque méthode de test (précédemment @ Before ) ** @ AfterEach - indique que la méthode annotée sera exécutée

après chaque méthode de test (précédemment @ After ) ** @ BeforeAll - indique que la méthode annotée sera exécutée

avant toutes les méthodes de test de la classe en cours (auparavant @ @ BeforeClass ) ** @ AfterAll - indique que la méthode annotée sera exécutée après

toutes les méthodes de test de la classe en cours (précédemment @ AfterClass ) ** @ Disable - il est utilisé pour désactiver une classe ou une méthode de test (précédemment

@Ignorer )

3.3. JUnit Vintage

Prend en charge l’exécution de tests basés sur JUnit 3 et JUnit 4 sur la plate-forme JUnit 5.

4. Annotations de base

Pour discuter des nouvelles annotations, nous avons divisé la section en groupes suivants, chargés de l’exécution: avant les tests, pendant les tests (facultatif) et après les tests:

4.1. @ BeforeAll et @ BeforeEach

Vous trouverez ci-dessous un exemple de code simple à exécuter avant les principaux cas de test:

@BeforeAll
static void setup() {
    log.info("@BeforeAll - executes once before all test methods in this class");
}

@BeforeEach
void init() {
    log.info("@BeforeEach - executes before each test method in this class");
}

Il est important de noter que la méthode avec l’annotation @ BeforeAll doit être statique, sinon le code ne sera pas compilé.

4.2. @ DisplayName et @ Disabled

Passons maintenant aux nouvelles méthodes optionnelles de test:

@DisplayName("Single test successful")
@Test
void testSingleSuccessTest() {
    log.info("Success");
}

@Test
@Disabled("Not implemented yet")
void testShowSomething() {
}

Comme nous pouvons le voir, nous pouvons changer le nom d’affichage ou désactiver la méthode avec un commentaire, en utilisant de nouvelles annotations.

4.3. @ AfterEach et @ AfterAll

Enfin, discutons des méthodes liées aux opérations après l’exécution des tests:

@AfterEach
void tearDown() {
    log.info("@AfterEach - executed after each test method.");
}

@AfterAll
static void done() {
    log.info("@AfterAll - executed after all test methods.");
}

Veuillez noter que la méthode avec @ AfterAll doit également être une méthode statique.

5. Assertions et hypothèses

Veuillez vous référer à ce lien:/junit-5-preview[tutoriel]sur JUnit5.

6. Test d’exception

Il existe deux manières de tester les exceptions dans JUnit 5. Les deux méthodes peuvent être implémentées à l’aide de la méthode assertThrows () :

@Test
void shouldThrowException() {
    Throwable exception = assertThrows(UnsupportedOperationException.class, () -> {
      throw new UnsupportedOperationException("Not supported");
    });
    assertEquals(exception.getMessage(), "Not supported");
}

@Test
void assertThrowsException() {
    String str = null;
    assertThrows(IllegalArgumentException.class, () -> {
      Integer.valueOf(str);
    });
}

Le premier exemple est utilisé pour vérifier plus de détails de l’exception levée et le second ne fait que valider le type d’exception.

7. Suites de test

Pour poursuivre les nouvelles fonctionnalités de JUnit 5, nous allons essayer de connaître le concept d’agrégation de plusieurs classes de test dans une suite de tests afin de pouvoir les exécuter ensemble. JUnit 5 fournit deux annotations:

@ SelectPackages et @ SelectClasses pour créer des suites de tests.

Gardez à l’esprit qu’à ce stade précoce, la plupart des IDE ne prennent pas en charge ces fonctionnalités.

Regardons le premier:

@RunWith(JUnitPlatform.class)
@SelectPackages("com.baeldung")
public class AllTests {}

@ SelectPackage est utilisé pour spécifier les noms des packages à sélectionner lors de l’exécution d’une suite de tests. Dans notre exemple, tous les tests seront exécutés. La deuxième annotation, @ SelectClasses , est utilisée pour spécifier les classes à sélectionner lors de l’exécution d’une suite de tests:

@RunWith(JUnitPlatform.class)
@SelectClasses({AssertionTest.class, AssumptionTest.class, ExceptionTest.class})
public class AllTests {}

Par exemple, la classe ci-dessus créera une suite contenant trois classes de test. Veuillez noter que les cours ne doivent pas obligatoirement être dans un seul paquet.

8. Tests dynamiques

Le dernier sujet que nous souhaitons aborder est la fonctionnalité de tests dynamiques JUnit 5, qui permet de déclarer et d’exécuter des scénarios de test générés au moment de l’exécution. Contrairement aux tests statiques qui définissent un nombre fixe de cas de test au moment de la compilation, les tests dynamiques nous permettent de définir le cas de test de manière dynamique au moment de l’exécution.

Les tests dynamiques peuvent être générés par une méthode factory annotée avec @TestFactory. Regardons l’exemple de code:

@TestFactory
public Stream<DynamicTest> translateDynamicTestsFromStream() {
    return in.stream()
      .map(word ->
          DynamicTest.dynamicTest("Test translate " + word, () -> {
            int id = in.indexOf(word);
            assertEquals(out.get(id), translate(word));
          })
    );
}

Cet exemple est très simple et facile à comprendre. Nous voulons traduire des mots en utilisant deux ArrayList , nommés respectivement in et out . La méthode d’usine doit renvoyer un Stream , Collection , Iterable ou Iterator . Dans notre cas, nous avons choisi Java 8 Stream.

Veuillez noter que les méthodes @ TestFactory ne doivent pas être privées ou statiques.

Le nombre de tests est dynamique et dépend de la taille de ArrayList .

9. Conclusion

La description était un bref aperçu des modifications à venir avec JUnit 5.

Nous pouvons voir que l’architecture de JUnit 5 a beaucoup évolué en ce qui concerne le lanceur de plateforme, l’intégration avec l’outil de construction, l’IDE, d’autres frameworks de test d’unité, etc. .

Les exemples utilisés dans cet article se trouvent dans le projet GitHub .