JUnit-Tests parallel zu Maven ausführen

Paralleles Ausführen von JUnit-Tests mit Maven

1. Einführung

Obwohl das serielle Ausführen von Tests meistens einwandfrei funktioniert. Manchmal müssen wir die Dinge möglicherweise beschleunigen. In diesen Situationen können parallele Tests hilfreich sein.

JUnit 4.7 and later versions make it possible to execute tests in parallel using Maven’s Surefire Plugin. Kurz gesagt, Surefire bietet zwei Möglichkeiten, um Tests parallel auszuführen:

  • Der erste Ansatz verwendet Multithreading in einem einzelnen JVM-Prozess

  • Während der zweite Ansatz mehrere JVM-Prozesse verwendet

In diesem Tutorial erfahren Sie, wie Sie Surefire so konfigurieren, dass JUnit-Tests in einem einzelnen JVM-Prozess parallel ausgeführt werden. Dann werden wir sehen, wie Tests in einem Maven-Multimodul-Projekt parallel ausgeführt werden.

2. Maven-Abhängigkeiten

Beginnen wir mit dem Importieren der erforderlichen Abhängigkeiten. 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. Parallele Tests ausführen

Um einen Test parallel auszuführen, sollten wir einen Testläufer verwenden, derorg.junit.runners.ParentRunner erweitert.

Selbst Tests, die keinen expliziten Testläufer deklarieren, funktionieren jedoch, da der Standardläufer diese Klasse erweitert.

Um die parallele Testausführung zu demonstrieren, verwenden wir als Nächstes eine Testsuite mit zwei Testklassen mit jeweils einigen Methoden. Tatsächlich würde jede Standardimplementierung einer JUnit-Testsuite ausreichen.

3.1. Verwenden paralleler Parameter

Aktivieren Sie zunächst das parallele Verhalten in Surefire mithilfe desparallel -Sparameters. It states the level of granularity at which we would like to apply parallelism.

Mögliche Werte sind:

  • methods – runs Testmethoden in separaten Threads

  • classes – führt Testklassen in separaten Threads aus

  • classesAndMethods – führt Klassen und Methoden in separaten Threads aus

  • suites – ronnensuiten parallel

  • suitesAndClasses – runs Suites und Klassen in separaten Threads

  • suitesAndMethods – erstellt separate Threads für Klassen und Methoden

  • all – führt Suites, Klassen sowie Methoden in separaten Threads aus

In unserem Beispiel verwenden wirall:


    all

Zweitens definieren wir die Gesamtzahl der Threads, die Surefire erstellen soll. Wir können das auf zwei Arten tun:

MitthreadCount, das die maximale Anzahl von Threads definiert, die Surefire erstellt:

10

Oder verwenden Sie den ParameteruseUnlimitedThreads, bei dem ein Thread pro CPU-Kern erstellt wird:

true

Standardmäßig istthreadCount pro CPU-Kern. Wir können den ParameterperCoreThreadCount verwenden, um dieses Verhalten zu aktivieren oder zu deaktivieren:

true

3.2. Thread-Count-Einschränkungen verwenden

Angenommen, wir möchten die Anzahl der Threads definieren, die auf Methoden-, Klassen- und Suite-Ebene erstellt werden sollen. We can do this with the threadCountMethods, threadCountClasses and threadCountSuites parameters.

Kombinieren wir diese Parameter mitthreadCount aus der vorherigen Konfiguration: _ _

2
2
6

Da wirall inparallel, we verwendet haben, haben wir die Thread-Anzahl für Methoden, Suites und Klassen definiert. Es ist jedoch nicht zwingend erforderlich, den Blattparameter zu definieren. Surefire leitet die Anzahl der zu verwendenden Threads ab, wenn Blattparameter weggelassen werden.

Wenn beispielsweisethreadCountMethods weggelassen wird, müssen wir nur sicherstellen, dassthreadCount>threadCountClasses  +threadCountSuites. ist

Manchmal möchten wir möglicherweise die Anzahl der Threads begrenzen, die für Klassen, Suites oder Methoden erstellt wurden, auch wenn wir eine unbegrenzte Anzahl von Threads verwenden.

Wir können auch in solchen Fällen Einschränkungen für die Threadanzahl anwenden:

true
2

3.3. Timeouts einstellen

Manchmal müssen wir sicherstellen, dass die Testausführung zeitlich begrenzt ist.

To do that we can use the parallelTestTimeoutForcedInSeconds parameter. Dies unterbricht aktuell laufende Threads und führt nach Ablauf des Timeouts keinen der in der Warteschlange befindlichen Threads aus:

5

Eine andere Option ist die Verwendung vonparallelTestTimeoutInSeconds.

In diesem Fall werden nur die Threads in der Warteschlange an der Ausführung gehindert:

3.5

Bei beiden Optionen werden die Tests jedoch mit einer Fehlermeldung beendet, wenn die Zeitüberschreitung abgelaufen ist.

3.4. Vorbehalte

Surefire ruft statische Methoden auf, die im übergeordneten Thread mit@Parameters,@BeforeClass und@AfterClass versehen sind. Stellen Sie daher sicher, dass Sie nach möglichen Speicherinkonsistenzen oder Rennbedingungen suchen, bevor Sie parallel Tests durchführen.

Tests, die den gemeinsam genutzten Status mutieren, sind definitiv keine guten Kandidaten für die parallele Ausführung.

4. Testausführung in Maven-Projekten mit mehreren Modulen

Bisher haben wir uns darauf konzentriert, Tests in einem Maven-Modul parallel auszuführen.

Angenommen, wir haben mehrere Module in einem Maven-Projekt. Da diese Module nacheinander erstellt werden, werden die Tests für jedes Modul auch nacheinander ausgeführt.

We can change this default behavior by using Maven’s -T parameter which builds modules in parallel. Dies kann auf zwei Arten erfolgen.

Wir können entweder die genaue Anzahl der Threads angeben, die beim Erstellen des Projekts verwendet werden sollen:

mvn -T 4 surefire:test

Oder verwenden Sie die portable Version und geben Sie die Anzahl der Threads an, die pro CPU-Kern erstellt werden sollen:

mvn -T 1C surefire:test

In beiden Fällen können wir Tests beschleunigen und Ausführungszeiten aufbauen.

5. Fazit

Zusammenfassend haben wir zunächst das Multithread-Verhalten aktiviert und den Grad der Parallelität mithilfe des Parametersparalleldefiniert. Anschließend haben wir die Anzahl der Threads, die Surefire erstellen soll, begrenzt. Später legen wir Timeout-Parameter fest, um die Testausführungszeiten zu steuern.

Schließlich haben wir untersucht, wie wir die Ausführungszeiten für Builds verkürzen und daher die Ausführungszeiten in Maven-Projekten mit mehreren Modulen testen können.

Wie immer lautet der hier dargestellte Codeavailable on GitHub.