Eine Anleitung zu JUnit 5

1. Überblick

JUnit ist eines der beliebtesten Frameworks für Unit-Testing im Java-Ökosystem. Obwohl die aktuelle stabile Version JUnit 4.12 ist, enthält eine Version 5.1.0 eine Reihe aufregender Neuerungen, mit dem Ziel , neue Funktionen in Java 8 und höher zu unterstützen und viele verschiedene Teststile zu ermöglichen.

Dieser Artikel folgt unserem Link:/junit-5-preview[Vorschau von JUnit 5].

2. Abhängigkeiten von Maven

Das Einrichten von JUnit 5.x.0 ist ziemlich einfach. Wir müssen unserem pom folgende Abhängigkeit hinzufügen. xml :

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

Es ist wichtig zu wissen, dass diese Version Java 8 erfordert, um zu funktionieren.

Darüber hinaus gibt es jetzt direkte Unterstützung für die Durchführung von Unit-Tests auf der JUnit-Plattform in Eclipse sowie auf IntelliJ. Sie können natürlich auch Tests mit dem Maven-Testziel ausführen.

Auf der anderen Seite unterstützt IntelliJ standardmäßig JUnit 5. Daher ist es sehr einfach, JUnit 5 unter IntelliJ auszuführen. Klicken Sie einfach mit der rechten Maustaste → Ausführen oder Strg-Umschalt-F10.

3. Die Architektur

JUnit 5 besteht aus mehreren verschiedenen Modulen aus drei verschiedenen Unterprojekten:

3.1. JUnit-Plattform

Die Plattform ist dafür verantwortlich, Test-Frameworks in der JVM zu starten.

Es definiert eine stabile und leistungsfähige Schnittstelle zwischen JUnit und seinem Client, z. B. Build-Tools.

Das Endziel ist die einfache Integration der Kunden in JUnit in die Ermittlung und Durchführung der Tests.

Sie definiert außerdem die TestEngine - API zum Entwickeln eines Testframeworks, das auf der JUnit-Plattform ausgeführt wird.

Auf diese Weise können Sie Test-Bibliotheken von Drittanbietern direkt in JUnit einfügen, indem Sie benutzerdefinierte TestEngine implementieren.

3.2. JUnit Jupiter

Dieses Modul enthält neue Programmier- und Erweiterungsmodelle zum Schreiben von Tests in JUnit 5. Neue Anmerkungen im Vergleich zu JUnit 4 sind:

  • @ TestFactory - bezeichnet eine Methode, die eine Testfabrik für Dynamik darstellt

Tests ** @ DisplayName - Definiert den benutzerdefinierten Anzeigenamen für eine Testklasse oder ein

Testmethode ** @ Nested - Gibt an, dass die annotierte Klasse verschachtelt und nicht statisch ist

Testklasse ** @ Tag - deklariert Tags für Filtertests

  • @ ExtendWith - wird zur Registrierung benutzerdefinierter Erweiterungen verwendet

  • @ BeforeEach – gibt an, dass die kommentierte Methode ausgeführt wird

vor jeder Testmethode (vorher @ Before ) ** @ AfterEach - Gibt an, dass die kommentierte Methode ausgeführt wird

nach jeder Testmethode (vorher @ After ) ** @ BeforeAll - Gibt an, dass die kommentierte Methode ausgeführt wird

vor allen Testmethoden in der aktuellen Klasse (vorher @ BeforeClass ) ** @ AfterAll - Gibt an, dass die kommentierte Methode danach ausgeführt wird

alle Testmethoden in der aktuellen Klasse (vorher @ AfterClass ) ** @ Disable - dient zum Deaktivieren einer Testklasse oder -methode (zuvor)

@Ignorieren )

3.3. JUnit Vintage

Unterstützt das Ausführen von JUnit 3- und JUnit 4-basierten Tests auf der JUnit 5-Plattform.

4. Grundlegende Anmerkungen

Um neue Anmerkungen zu diskutieren, haben wir den Abschnitt in die folgenden Gruppen unterteilt, die für die Ausführung verantwortlich sind: vor den Tests, während der Tests (optional) und nach den Tests:

4.1. @ BeforeAll und @ BeforeEach

Im Folgenden finden Sie ein Beispiel für den einfachen Code, der vor den Haupttestfällen ausgeführt wird:

@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");
}

Beachten Sie, dass die Methode mit der Annotation @ BeforeAll statisch sein muss, andernfalls wird der Code nicht kompiliert.

4.2. @ DisplayName und @ Disabled

Lassen Sie uns zu neuen optionalen Testmethoden übergehen:

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

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

Wie wir sehen, können wir den Anzeigenamen ändern oder die Methode mit einem Kommentar unter Verwendung neuer Anmerkungen deaktivieren.

4.3. @ AfterEach und @ AfterAll

Lassen Sie uns zum Schluss Methoden diskutieren, die nach der Testausführung mit Operationen verbunden sind:

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

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

Bitte beachten Sie, dass die Methode mit @ AfterAll auch eine statische Methode sein muss.

5. Behauptungen und Annahmen

Bitte beachten Sie diesen Link:/junit-5-preview[Tutorial]zu JUnit5.

6. Ausnahmetest

Es gibt zwei Möglichkeiten für Ausnahmetests in JUnit 5. Beide können mithilfe der assertThrows () -Methode implementiert werden:

@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);
    });
}

Das erste Beispiel wird verwendet, um mehr Details der ausgelösten Ausnahme zu überprüfen, und das zweite Beispiel überprüft nur den Typ der Ausnahme.

7. Test Suiten

Um die neuen Funktionen von JUnit 5 fortzusetzen, werden wir versuchen, das Konzept der Zusammenfassung mehrerer Testklassen in einer Testsuite kennenzulernen, damit wir diese gemeinsam ausführen können. JUnit 5 bietet zwei Anmerkungen:

@ SelectPackages und @ SelectClasses zum Erstellen von Testsuiten.

Beachten Sie, dass die meisten IDEs zu diesem frühen Zeitpunkt diese Funktionen nicht unterstützen.

Schauen wir uns den ersten an:

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

@ SelectPackage wird verwendet, um die Namen der Pakete anzugeben, die beim Ausführen einer Testsuite ausgewählt werden sollen. In unserem Beispiel werden alle Tests ausgeführt. Die zweite Anmerkung, @ SelectClasses , wird verwendet, um die Klassen anzugeben, die beim Ausführen einer Testsuite ausgewählt werden sollen:

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

Die obige Klasse erstellt beispielsweise eine Suite, die drei Testklassen enthält. Bitte beachten Sie, dass die Klassen nicht in einem einzigen Paket sein müssen.

8. Dynamische Tests

Das letzte Thema, das wir einführen möchten, ist die Funktion JUnit 5 Dynamic Tests, mit der zur Laufzeit generierte Testfälle deklariert und ausgeführt werden können. Im Gegensatz zu den statischen Tests, die eine festgelegte Anzahl von Testfällen zur Kompilierzeit definieren, können mit den dynamischen Tests die Testfälle dynamisch zur Laufzeit definiert werden.

Dynamische Tests können mit einer Factory-Methode generiert werden, die mit @TestFactory versehen ist. Schauen wir uns das Codebeispiel an:

@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));
          })
    );
}

Dieses Beispiel ist sehr einfach und leicht verständlich. Wir möchten Wörter mit zwei ArrayList namens in und out übersetzen. Die Factory-Methode muss Stream , Collection , Iterable oder Iterator zurückgeben. In unserem Fall wählen wir Java 8 Stream.

Bitte beachten Sie, dass @ TestFactory -Methoden nicht privat oder statisch sein dürfen.

Die Anzahl der Tests ist dynamisch und hängt von der Größe der ArrayList ab.

9. Fazit

Der Bericht war ein kurzer Überblick über die Änderungen, die mit JUnit 5 einhergehen.

Wir sehen, dass JUnit 5 eine große Änderung in seiner Architektur aufweist, die sich auf Plattformstart, Integration mit Build-Tool, IDE, andere Unit-Test-Frameworks usw. bezieht. Darüber hinaus ist JUnit 5 stärker in Java 8 integriert, insbesondere in Lambdas- und Stream-Konzepte .

Die in diesem Artikel verwendeten Beispiele finden Sie im GitHub-Projekt .