JUnit5 Tutorial
In diesem Junit Tutorial werden wir die Grundlagen von JUnit5 und seine neuen Funktionen anhand von Beispielen vorstellen. In der Java-Welt ist JUnit eines der beliebten Frameworks, um Unit-Tests gegen Java-Code zu implementieren. JUnit hilft Entwicklern vor allem dabei, ihren Code auf der JVM selbst zu testen.
JUnit5 Architektur
JUnit Plattform
- Startet Test-Frameworks auf der JVM
- Verfügt über eine TestEngine API, die verwendet wird, um ein Test-Framework zu erstellen, das auf der JUnit-Plattform läuft
JUnit Jupiter
- Mischung aus neuem Programmiermodell zum Schreiben von Tests und Erweiterungsmodell für Erweiterungen
- Hinzufügung neuer Annotationen wie @BeforeEach, @AfterEach, @AfterAll, @BeforeAll usw.
JUnit Vintage
- Bietet Unterstützung, um vorherige JUnit-Versionen 3 und 4 Tests auf dieser neuen Plattform auszuführen
JUnit Maven-Abhängigkeiten
Um JUnit5-basierte Testfälle in einem Projekt zu implementieren, füge die folgende Abhängigkeit zur pom.xml Datei des Projekts hinzu:
JUnit 5 Bibliothek
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version> 1.1.1</version>
<scope>test</scope>
</dependency>
JUnit5 maven surefire provider, um die Unit-Tests auszuführen, wo IDE keine JUnit5-Unterstützung hat (wenn IDE Unterstützung hat, ist dieser Punkt nicht erforderlich)
<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>
JUnit5 maven surefire provider um die Unit Tests auszuführen, wenn die IDE keine JUnit5 Unterstützung hat (wenn die IDE Unterstützung hat, dann ist dieser Punkt nicht erforderlich)
<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>
JUnit5 Neue Funktionen
Es benötigt Java 8 oder höher zur Laufzeit. Man kann jedoch weiterhin Code testen, der mit früheren Java-Versionen kompiliert wurde. Es wurden verschiedene neue Funktionen eingeführt.
JUnit Annotationen
Nachfolgend sind einige häufig verwendete Annotationen aufgeführt:
Annotation | Beschreibung |
---|---|
@Test | Bezeichnet eine Testmethode |
@DisplayName | Deklariert einen benutzerdefinierten Anzeigenamen für die Testklasse oder Testmethode |
@BeforeEach | Bezeichnet, dass die annotierte Methode vor jeder Testmethode ausgeführt werden soll |
@AfterEach | Bezeichnet, dass die annotierte Methode nach jeder Testmethode ausgeführt werden soll |
@BeforeAll | Bezeichnet, dass die annotierte Methode vor allen Testmethoden ausgeführt werden soll |
@AfterAll | Bezeichnet, dass die annotierte Methode nach allen Testmethoden ausgeführt werden soll |
@Disable | Wird verwendet, um eine Testklasse oder Testmethode zu deaktivieren |
@Nested | Bezeichnet, dass die annotierte Klasse eine verschachtelte, nicht-statische Testklasse ist |
@Tag | Deklariert Tags für die Filterung von Tests |
@ExtendWith | Registriert benutzerdefinierte Erweiterungen |
package com.journaldev;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class JUnit5Sample1Test {
@BeforeAll
static void beforeAll() {
System.out.println("**--- Executed once before all test methods in this class ---**");
}
@BeforeEach
void beforeEach() {
System.out.println("**--- Executed before each test method in this class ---**");
}
@Test
void testMethod1() {
System.out.println("**--- Test method1 executed ---**");
}
@DisplayName("Test method2 with condition")
@Test
void testMethod2() {
System.out.println("**--- Test method2 executed ---**");
}
@Test
@Disabled("implementation pending")
void testMethod3() {
System.out.println("**--- Test method3 executed ---**");
}
@AfterEach
void afterEach() {
System.out.println("**--- Executed after each test method in this class ---**");
}
@AfterAll
static void afterAll() {
System.out.println("**--- Executed once after all test methods in this class ---**");
}
}
Wir können obige JUnit-Testklasse in Eclipse -> Run As -> JUnit Test ausführen.
JUnit Assertions
Jede Testmethode muss mit Hilfe von Assertions gegen die Bedingung true ausgewertet werden, damit der Test weiter ausgeführt werden kann. JUnit Jupiter Assertions sind in der Klasse org.junit.jupiter.api.Assertions enthalten. Alle Methoden sind statisch.
Assertion | Beschreibung |
---|---|
assertEquals(expected, actual) | Schlägt fehl, wenn das Erwartete nicht dem Tatsächlichen entspricht |
assertFalse(expression) | Schlägt fehl, wenn der Ausdruck nicht falsch ist |
assertNull(actual) | Schlägt fehl, wenn das Tatsächliche nicht null ist |
assertNotNull(actual) | Schlägt fehl, wenn das Tatsächliche null ist |
assertAll() | Gruppiert viele Assertions, und jede Assertion wird ausgeführt, auch wenn eine oder mehrere davon fehlschlagen |
assertTrue(expression) | Schlägt fehl, wenn der Ausdruck nicht wahr ist |
assertThrows() | Es wird erwartet, dass die zu testende Klasse eine Ausnahme wirft |
JUnit5 Tutorial – Imports
Testklassen benötigen das org.junit.jupiter.api.Test Import-Statement und nicht org.junit.Test. Außerdem müssen die Testmethoden nicht öffentlich und lokal zum Paket sein.
import org.junit.jupiter.api.Test;
JUnit5 Tutorial – Annahmen
Annahmen sind statische Methoden in der Klasse org.junit.jupiter.api.Assumptions. Sie führen einen Test nur aus, wenn die spezifizierte Bedingung erfüllt ist, andernfalls wird der Test abgebrochen. Der abgebrochene Test führt nicht zum Build-Fehler. Wenn eine Annahme fehlschlägt, wird eine org.opentest4j.TestAbortedException geworfen und der Test wird übersprungen.
Annahmen | Beschreibung |
---|---|
assumeTrue | Führt den Körper des Lambda aus, wenn die positive Bedingung zutrifft, andernfalls wird der Test übersprungen |
assumeFalse | Führt den Körper des Lambda aus, wenn die negative Bedingung zutrifft, andernfalls wird der Test übersprungen |
assumingThat | Ein Teil der Testmethode wird ausgeführt, wenn eine Annahme zutrifft, und alles nach dem Lambda wird ausgeführt, unabhängig davon, ob die Annahme in assumingThat() zutrifft oder nicht |
@Test
void testAssumeTrue() {
boolean b = 'A' == 'A';
assumeTrue(b);
assertEquals("Hello", "Hello");
}
@Test
@DisplayName("test executes only on Saturday")
public void testAssumeTrueSaturday() {
LocalDateTime dt = LocalDateTime.now();
assumeTrue(dt.getDayOfWeek().getValue() == 6);
System.out.println("further code will execute only if above assumption holds true");
}
@Test
void testAssumeFalse() {
boolean b = 'A' != 'A';
assumeFalse(b);
assertEquals("Hello", "Hello");
}
@Test
void testAssumeFalseEnvProp() {
System.setProperty("env", "prod");
assumeFalse("dev".equals(System.getProperty("env")));
System.out.println("further code will execute only if above assumption hold");
}
@Test
void testAssumingThat() {
System.setProperty("env", "test");
assumingThat("test".equals(System.getProperty("env")),
() -> {
assertEquals(10, 10);
System.out.println("perform below assertions only on the test env");
});
assertEquals(20, 20);
System.out.println("perform below assertions on all env");
}
JUnit Verschachtelte Testklassen
Verschachtelte Tests ermöglichen es, verschachtelte Klassen zu erstellen und alle ihre Testmethoden auszuführen. Die inneren Klassen müssen nicht statisch sein. Annotiere einfach innere Klassen mit @Nested, und alle Testmethoden darin werden ausgeführt.
@BeforeAll
static void beforeAll() {
System.out.println("**--- JUnit5Sample4Test :: beforeAll :: Executed once before all test methods ---**");
}
@BeforeEach
void beforeEach() {
System.out.println("**--- JUnit5Sample4Test :: beforeEach :: Executed before each test method ---**");
}
@AfterEach
void afterEach() {
System.out.println("**--- JUnit5Sample4Test :: afterEach :: Executed after each test method ---**");
}
@AfterAll
static void afterAll() {
System.out.println("**--- JUnit5Sample4Test :: afterAll :: Executed after all test method ---**");
}
@Nested
class InnerClass {
@BeforeEach
void beforeEach() {
System.out.println("**--- InnerClass :: beforeEach :: Executed before each test method ---**");
}
@AfterEach
void afterEach() {
System.out.println("**--- InnerClass :: afterEach :: Executed after each test method ---**");
}
@Test
void testMethod1() {
System.out.println("**--- InnerClass :: testMethod1 :: Executed test method1 ---**");
}
@Nested
class InnerMostClass {
@BeforeEach
void beforeEach() {
System.out.println("**--- InnerMostClass :: beforeEach :: Executed before each test method ---**");
}
@AfterEach
void afterEach() {
System.out.println("**--- InnerMostClass :: afterEach :: Executed after each test method ---**");
}
@Test
void testMethod2() {
System.out.println("**--- InnerMostClass :: testMethod2 :: Executed test method2 ---**");
}
}
}
JUnit Test Ausnahme
Es gibt Situationen, in denen erwartet wird, dass Methoden unter einer bestimmten Bedingung eine Ausnahme werfen. assertThrows wird den Test fehlschlagen lassen, wenn die gegebene Methode nicht die spezifizierte Ausnahme wirft.
Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("Illegal Argument Exception occured");
});
assertEquals("Illegal Argument Exception occured", exception.getMessage());
JUnit Testausführung
Die Unit-Tests können auf viele Arten ausgeführt werden, zwei der Möglichkeiten sind wie folgt:
- Verwende die Eclipse IDE Oxygen.3a (4.7.3a) Release und öffne die zu ausführende Testdatei. Rechtsklicke auf die Datei und wähle die Option Ausführen als gefolgt von JUnit-Test
- Verwende den Befehl mvn test auf der Windows-Kommandozeile
Zusammenfassung – JUnit5 Tutorial
Wir haben JUnit5 und seine neuen Funktionen mit einigen Beispielen für Einsteiger erkundet. Wir haben auch gesehen, wie wir JUnit-Annotationen, Assertions, Annahmen, Ausnahmen verwenden und verschachtelte Testklassen schreiben können.