Exécution de tests JUnit en parallèle avec Maven

Exécution de tests JUnit en parallèle avec Maven

1. introduction

Bien que l'exécution de tests en série fonctionne très bien la plupart du temps. Parfois, nous pouvons avoir besoin d'accélérer les choses. Dans ces situations, des tests parallèles peuvent aider.

JUnit 4.7 and later versions make it possible to execute tests in parallel using Maven’s Surefire Plugin. En résumé, Surefire propose deux méthodes pour exécuter des tests en parallèle:

  • La première approche utilise le multithreading dans un seul processus JVM

  • Alors que la seconde approche utilise plusieurs processus JVM

Dans ce didacticiel, nous allons expliquer comment configurer Surefire pour exécuter des tests JUnit en parallèle dans un seul processus JVM. Ensuite, nous verrons comment exécuter des tests en parallèle dans un projet multimodule Maven.

2. Dépendances Maven

Commençons par importer les dépendances requises. We’ll need to use JUnit 4.7 or later along with Surefire 2.16 or later:


    junit
    junit
    4.12
    test

    org.apache.maven.plugins
    maven-surefire-plugin
    2.22.0

3. Exécution de tests parallèles

Pour exécuter un test en parallèle, nous devons utiliser un testeur qui étendorg.junit.runners.ParentRunner.

Cependant, même les tests qui ne déclarent pas d'exécuteur de test explicite fonctionnent, car l'exécuteur par défaut étend cette classe.

Ensuite, pour démontrer l'exécution de tests parallèles, nous utiliserons une suite de tests avec deux classes de test ayant chacune quelques méthodes. En fait, toute implémentation standard d’une suite de tests JUnit ferait l'affaire.

3.1. Utilisation du paramètre parallèle

Tout d'abord, activons le comportement parallèle dans Surefire à l'aide du sparamètreparallel . It states the level of granularity at which we would like to apply parallelism.

Les valeurs possibles sont:

  • methods – exécute les méthodes de test dans des threads séparés

  • classes – exécute des classes de test dans des threads séparés

  • classesAndMethods – exécute des classes et des méthodes dans des threads séparés

  • suites – ruites soleils en parallèle

  • suitesAndClasses – exécute des suites et des classes dans des threads séparés

  • suitesAndMethods – creates des threads séparés pour les classes et pour les méthodes

  • all – exécute des suites, des classes ainsi que des méthodes dans des threads séparés

Dans notre exemple, nous utilisonsall:


    all

Deuxièmement, définissons le nombre total de threads que nous voulons que Surefire crée. Nous pouvons le faire de deux manières:

En utilisantthreadCount qui définit le nombre maximum de threads que Surefire créera:

10

Ou en utilisant le paramètreuseUnlimitedThreads où un thread est créé par cœur de processeur:

true

Par défaut,threadCount correspond à chaque cœur de processeur. Nous pouvons utiliser le paramètreperCoreThreadCount pour activer ou désactiver ce comportement:

true

3.2. Utilisation des limitations du nombre de threads

Supposons maintenant que nous souhaitons définir le nombre de threads à créer au niveau de la méthode, de la classe et de la suite. We can do this with the threadCountMethods, threadCountClasses and threadCountSuites parameters.

Combinons ces paramètres avecthreadCount de la configuration précédente: _ _

2
2
6

Depuis que nous avons utiliséall dansparallel, , swe’ve défini le nombre de threads pour les méthodes, les suites ainsi que les classes. Cependant, il n’est pas obligatoire de définir le paramètre feuille. Surefire en déduit le nombre de threads à utiliser dans le cas où les paramètres feuille sont omis.

Par exemple, sithreadCountMethods est omis, nous devons simplement nous assurer quethreadCount>threadCountClasses  +threadCountSuites.

Parfois, nous pouvons vouloir limiter le nombre de threads créés pour des classes, des suites ou des méthodes, même si nous utilisons un nombre illimité de threads.

Nous pouvons également appliquer des limitations de nombre de threads:

true
2

3.3. Définition des délais d'attente

Parfois, nous pouvons avoir besoin de nous assurer que l'exécution du test est limitée dans le temps.

To do that we can use the parallelTestTimeoutForcedInSeconds parameter. Cela interrompra les threads en cours d'exécution et n'exécutera aucun des threads en file d'attente une fois le délai écoulé:

5

Une autre option consiste à utiliserparallelTestTimeoutInSeconds.

Dans ce cas, seuls les threads en file d'attente seront empêchés de s'exécuter:

3.5

Néanmoins, avec les deux options, les tests se termineront par un message d'erreur une fois le délai d'attente écoulé.

3.4. Mises en garde

Surefire appelle des méthodes statiques annotées avec@Parameters,@BeforeClass et@AfterClass dans le thread parent. Assurez-vous donc de vérifier les incohérences potentielles dans la mémoire ou les conditions de concurrence avant d'exécuter des tests en parallèle.

En outre, les tests qui muent en état partagé ne sont certainement pas de bons candidats pour une exécution en parallèle.

4. Exécution de tests dans des projets Maven multi-modules

Jusqu'à présent, nous nous sommes concentrés sur l'exécution de tests en parallèle dans un module Maven.

Mais disons que nous avons plusieurs modules dans un projet Maven. Puisque ces modules sont construits séquentiellement, les tests de chaque module sont également exécutés séquentiellement.

We can change this default behavior by using Maven’s -T parameter which builds modules in parallel. Ceci peut être fait de deux façons.

Nous pouvons soit spécifier le nombre exact de threads à utiliser lors de la construction du projet:

mvn -T 4 surefire:test

Ou utilisez la version portable et spécifiez le nombre de threads à créer par cœur de processeur:

mvn -T 1C surefire:test

Dans les deux cas, nous pouvons accélérer les tests et augmenter les temps d’exécution.

5. Conclusion

Pour résumer, nous avons commencé par activer le comportement multi-thread et définir le degré de parallélisme à l'aide du paramètreparallel. Par la suite, nous avons appliqué des limitations au nombre de threads que Surefire devrait créer. Plus tard, nous avons défini des paramètres de délai pour contrôler les temps d'exécution des tests.

Enfin, nous avons étudié les moyens de réduire les temps d’exécution des versions et, par conséquent, de tester les temps d’exécution dans les projets Maven multi-modules.

Comme toujours, le code présenté ici estavailable on GitHub.