Les bases de JUnit 5 - Un aperçu

1. Vue d’ensemble

JUnit est l’un des frameworks de tests unitaires les plus populaires pour Java. C’est donc un gros problème pour la communauté des développeurs lorsque de nouvelles versions majeures sortent. Une version alpha de JUnit 5 a été publiée début février et contient plusieurs innovations intéressantes.

Cet article explore les nouvelles fonctionnalités de cette version et les principales différences avec les versions précédentes.

2. Dépendances et configuration

L’installation de JUnit 5 est assez simple. Ajoutez simplement la dépendance suivante à votre pom.xml :

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

Cependant, pour l’instant, aucun IDE ne prend en charge JUnit 5, vous devrez donc également spécifier un script de construction:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <dependencies>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-surefire-provider</artifactId>
            <version>1.0.2</version>
        </dependency>
    </dependencies>
</plugin>

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

Lorsque vous créez un test, veillez à importer org.junit.jupiter.api.Test

3. Quoi de neuf

JUnit 5 tente de tirer pleinement parti des nouvelles fonctionnalités de Java 8, en particulier des expressions lambda.

3.1. Assertions

Les assertions ont été déplacées vers org.junit.jupiter.api.Assertions et ont été considérablement améliorées. Comme mentionné précédemment, vous pouvez maintenant utiliser lambdas dans les assertions:

@Test
void lambdaExpressions() {
    assertTrue(Stream.of(1, 2, 3)
      .stream()
      .mapToInt(i -> i)
      .sum() > 5, () -> "Sum should be greater than 5");
}

Bien que l’exemple ci-dessus soit trivial, l’un des avantages de l’utilisation de l’expression lambda pour le message d’assertion est qu’elle est évaluée paresseusement, ce qui permet de gagner du temps et des ressources si la construction du message est coûteuse.

Il est également maintenant possible de grouper des assertions avec assertAll () , qui signalera toutes les assertions ayant échoué au sein du groupe avec un MultipleFailuresError :

 @Test
 void groupAssertions() {
     int[]numbers = {0, 1, 2, 3, 4};
     assertAll("numbers",
         () -> assertEquals(numbers[0], 1),
         () -> assertEquals(numbers[3], 3),
         () -> assertEquals(numbers[4], 1)
     );
 }

Cela signifie qu’il est maintenant plus sûr de faire des assertions plus complexes, car vous serez en mesure de localiser l’emplacement exact de tout échec.

3.2. Hypothèses

Les hypothèses sont utilisées pour exécuter des tests uniquement si certaines conditions sont remplies.

Ceci est généralement utilisé pour les conditions externes nécessaires au bon fonctionnement du test, mais qui ne sont pas directement liées à ce qui est testé.

Vous pouvez déclarer une hypothèse avec assumeTrue () , assumeFalse () et assumingThat () .

@Test
void trueAssumption() {
    assumeTrue(5 > 1);
    assertEquals(5 + 2, 7);
}

@Test
void falseAssumption() {
    assumeFalse(5 < 1);
    assertEquals(5 + 2, 7);
}

@Test
void assumptionThat() {
    String someString = "Just a string";
    assumingThat(
        someString.equals("Just a string"),
        () -> assertEquals(2 + 2, 4)
    );
}

Si une hypothèse échoue, une TestAbortedException est levée et le test est simplement ignoré.

Les hypothèses comprennent également les expressions lambda.

3.3. Exceptions

JUnit 5 améliore la prise en charge des exceptions. Une méthode assertThrows () a été ajoutée pour vérifier qu’une expression renvoie une expression d’un type donné:

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

Comme le montre l’exemple, JUnit 5 offre davantage de contrôle sur les exceptions levées que JUnit 4 ne le faisait auparavant. L’implication la plus évidente est qu’il est maintenant possible d’obtenir facilement toutes les informations dont nous pourrions avoir besoin à propos de l’exception, comme nous l’avons fait dans notre exemple en inspectant le message d’exception.

3.4. Tests imbriqués

Des tests imbriqués ont été ajoutés pour permettre aux développeurs d’exprimer des relations complexes entre différents groupes de tests. La syntaxe est assez simple: il vous suffit d’annoter une classe interne avec @Nested.

La documentation de JUnit propose un example élaboré, qui illustre l’une des utilisations possibles.

3.5. Désactivation des tests

Les tests peuvent maintenant être désactivés avec l’annotation @ Disabled .

@Test
@Disabled
void disabledTest() {
    assertTrue(false);
}

Ce test ne sera pas exécuté. L’annotation @ Disabled peut être appliquée à un scénario de test ou à une méthode de test et est équivalente à @ Ignore de JUnit 4.

3.6. Marquage

Les balises remplacent Categories de JUnit 4. Les balises peuvent être appliquées avec l’annotation @ Tag . Celles-ci permettent aux développeurs de grouper et de filtrer les tests.

@Tag("Test case")
public class TaggedTest {

    @Test
    @Tag("Method")
    void testMethod() {
        assertEquals(2+2, 4);
    }
}

4. Conclusion

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

Il est important de noter qu’au moment de la rédaction, seule la version Alpha était disponible, de sorte que certaines choses pourraient encore changer avant la publication.

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