web-dev-qa-db-fra.com

Exécution de tests JUnit 4 et JUnit 5 dans une même build

Dans les projets Maven, j'ai des tests existants reposant sur JUnit 4. Je ne peux pas migrer ces tests dans JUnit 5 pour plusieurs raisons.
Essentiellement, certains tests dépendent d'une bibliothèque qui utilise le runner JUnit 4 et la migration de code peut prendre du temps.

J'aimerais tout de même créer de nouvelles classes de test avec JUnit 5 qui est maintenant sorti et qui offre de nouvelles fonctionnalités intéressantes.
Comment faire ça ?

23
davidxxx

JUnit 5 fournit n moyen de sortir de la boîte .

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

Chacun est un projet distinct et leur utilisation permet de compiler et d'exécuter des tests JUnit 4 et JUnit 5 dans un même projet.

JUnit Jupiter est la combinaison du nouveau modèle de programmation et du modèle d'extension pour l'écriture de tests et d'extensions dans JUnit 5.

JUnit Vintage fournit un TestEngine pour exécuter des tests basés sur JUnit 3 et JUnit 4 sur la plate-forme.

La plate-forme JUnit sert de base au lancement de frameworks de test sur la JVM


Mise à jour: de Maven Surefire 2.22.0

De la documentation JUnit 5 :

À partir de la version 2.22.0, Maven Surefire fournit un support natif pour l'exécution des tests sur la plate-forme JUnit.

La configuration est donc beaucoup plus simple.
Notez que le junit-4 la dépendance api est facultative car les dépendances engine qui sont maintenant requises tirent déjà une version par défaut api (c'est le cas pour les junit 4 et 5).

Voici un exemple pom.xml.

<project xmlns="http://maven.Apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>david</groupId>
    <artifactId>jupiter-4-and-5-same-build</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit-jupiter.version>5.1.0</junit-jupiter.version>
        <!-- optional : if we want to use a junit4 specific version -->
        <junit.version>4.12</junit.version>
    </properties>
    <dependencies>
        <!--JUnit Jupiter Engine to depend on the JUnit5 engine and JUnit 5 API -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <!--JUnit Jupiter Engine to depend on the JUnit4 engine and JUnit 4 API  -->
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>${junit-jupiter.version}</version>
        </dependency>
        <!-- Optional : override the JUnit 4 API version provided by junit-vintage-engine -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
            </plugin>
        </plugins>
    </build>

</project>

Sur mon espace GitHub, j'ai ajouté un exemple de projet maven fonctionnel que vous pouvez parcourir/cloner. URL: https://github.com/ebundy/junit4-and-5-minimal-maven-project


Ancienne façon: pour Maven Surefire ci-dessous 2.22.0

Voici la configuration minimale à utiliser avec Maven pour configurer le projet pour compiler et exécuter les tests JUnit4 et JUnit5:

<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>mygroup</groupId>
    <artifactId>minimal-conf-junit4-5</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <!-- JUnit 5 depends on JDK 1.8 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!--  JUnit dependency versions -->
        <junit.version>4.12</junit.version>
        <junit-vintage-engine>4.12.1</junit-vintage-engine>
        <junit-jupiter.version>5.0.1</junit-jupiter.version>
        <junit-platform.version>1.0.1</junit-platform.version>
    </properties>

    <dependencies>
        <!--JUnit Jupiter API to write and compile tests with JUnit5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit 4 to make legacy JUnit 4 tests compile -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version> <!-- matters until now-->
                <dependencies>
                    <!-- to let surefire to run JUnit 4 but also JUnit 5 tests -->
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>${junit-platform.version}</version>
                    </dependency>
                    <!-- JUnit vintage engine to run JUnit 3 or JUnit 4 tests -->
                    <dependency>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                        <version>${junit-vintage-engine}</version>
                    </dependency>
                    <!-- JUnit 5 engine to run JUnit 5 tests -->
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>${junit-jupiter.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

À présent mvn test compile et exécute les tests JUnit 4 et JUnit 5.

Remarque 1: le junit-vintage-engine (4.12.1) et le junit (4.12) les dépendances ne spécifient pas la même version exacte.
Ce n'est pas du tout un problème car:

  • leur libération n'est pas liée entre eux

  • junit-vintage-engine est conçu pour exécuter tous les tests JUnit 3 ou 4 .

Note 2: maven-surefire-plugin avec le 2.19.1 la version importe ce que vous voulez pour compiler les classes de test JUnit 5 ou les classes de test JUnit 4 et JUnit 5.
La prochaine version du plugin provoque en effet quelques exceptions lors de l'exécution des tests JUnit 5 mais le 2.22.0 qui résout enfin le problème (voir la première partie de la réponse: " Mise à jour: depuis Maven Surefire 2.22.0").

35
davidxxx