Programmgesteuertes Ausführen von JUnit-Tests über eine Java-Anwendung

1. Übersicht

In diesem Tutorial zeigen wir, wie JUnit-Tests direkt aus Java-Code ausgeführt werden. Es gibt Szenarien, in denen diese Option nützlich ist.

Wenn Sie JUnit noch nicht kennen oder ein Upgrade auf JUnit 5 durchführen möchten, können Sie einige der vielen Tutorials zu diesem Thema lesen.

2. Maven-Abhängigkeiten

Wir benötigen einige grundlegende Abhängigkeiten, um sowohl JUnit 4- als auch JUnit 5-Tests auszuführen:

  org.junit.jupiter junit-jupiter-engine 5.2.0 test   org.junit.platform junit-platform-launcher 1.2.0   // for JUnit 4  junit junit 4.12 test 

Die neuesten Versionen von JUnit 4, JUnit 5 und JUnit Platform Launcher finden Sie in Maven Central.

3. Ausführen von JUnit 4-Tests

3.1. Testszenario

Sowohl für JUnit 4 als auch für JUnit 5 richten wir einige Platzhalter-Testklassen ein, die ausreichen, um unsere Beispiele zu demonstrieren:

public class FirstUnitTest { @Test public void whenThis_thenThat() { assertTrue(true); } @Test public void whenSomething_thenSomething() { assertTrue(true); } @Test public void whenSomethingElse_thenSomethingElse() { assertTrue(true); } }
public class SecondUnitTest { @Test public void whenSomething_thenSomething() { assertTrue(true); } @Test public void whensomethingElse_thenSomethingElse() { assertTrue(true); } }

Bei Verwendung von JUnit 4 erstellen wir Testklassen , die jeder Testmethode eine @ Test-Annotation hinzufügen .

Wir können auch andere nützliche Anmerkungen hinzufügen, z. B. @Before oder @After , aber das ist nicht im Umfang dieses Tutorials enthalten.

3.2. Ausführen einer einzelnen Testklasse

Um JUnit-Tests mit Java-Code auszuführen, können Sie die JUnitCore- Klasse verwenden (mit einer zusätzlichen TextListener- Klasse, mit der die Ausgabe in System.out angezeigt wird ):

JUnitCore junit = new JUnitCore(); junit.addListener(new TextListener(System.out)); junit.run(FirstUnitTest.class);

Auf der Konsole wird eine sehr einfache Meldung angezeigt, die auf erfolgreiche Tests hinweist:

Running one test class: .. Time: 0.019 OK (2 tests)

3.3. Ausführen mehrerer Testklassen

Wenn wir mit JUnit 4 mehrere Testklassen angeben möchten , können wir denselben Code wie für eine einzelne Klasse verwenden und einfach die zusätzlichen Klassen hinzufügen:

JUnitCore junit = new JUnitCore(); junit.addListener(new TextListener(System.out)); Result result = junit.run( FirstUnitTest.class, SecondUnitTest.class); resultReport(result);

Beachten Sie, dass das Ergebnis in einer Instanz der Ergebnisklasse von JUnit gespeichert ist , die wir mit einer einfachen Dienstprogrammmethode ausdrucken:

public static void resultReport(Result result) { System.out.println("Finished. Result: Failures: " + result.getFailureCount() + ". Ignored: " + result.getIgnoreCount() + ". Tests run: " + result.getRunCount() + ". Time: " + result.getRunTime() + "ms."); } 

3.4. Ausführen einer Testsuite

Wenn wir einige Testklassen gruppieren müssen, um sie auszuführen, können wir eine TestSuite erstellen . Dies ist nur eine leere Klasse, in der wir alle Klassen mithilfe von JUnit-Annotationen angeben:

@RunWith(Suite.class) @Suite.SuiteClasses({ FirstUnitTest.class, SecondUnitTest.class }) public class MyTestSuite { }

Um diese Tests auszuführen, verwenden wir wieder denselben Code wie zuvor:

JUnitCore junit = new JUnitCore(); junit.addListener(new TextListener(System.out)); Result result = junit.run(MyTestSuite.class); resultReport(result);

3.5. Wiederholte Tests ausführen

Eine der interessanten Funktionen von JUnit ist, dass wir Tests wiederholen können, indem wir Instanzen von RepeatedTest erstellen . Dies kann sehr hilfreich sein, wenn wir zufällige Werte testen oder um die Leistung zu überprüfen.

Im nächsten Beispiel führen wir die Tests von MergeListsTest fünfmal aus:

Test test = new JUnit4TestAdapter(FirstUnitTest.class); RepeatedTest repeatedTest = new RepeatedTest(test, 5); JUnitCore junit = new JUnitCore(); junit.addListener(new TextListener(System.out)); junit.run(repeatedTest);

Hier verwenden wir JUnit4TestAdapter als Wrapper für unsere Testklasse .

Wir können sogar programmgesteuert Suiten erstellen, indem wir wiederholte Tests durchführen:

TestSuite mySuite = new ActiveTestSuite(); JUnitCore junit = new JUnitCore(); junit.addListener(new TextListener(System.out)); mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(FirstUnitTest.class), 5)); mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(SecondUnitTest.class), 3)); junit.run(mySuite);

4. Ausführen von JUnit 5-Tests

4.1. Testszenario

Mit JUnit 5 verwenden wir dieselben Beispieltestklassen wie für die vorherige Demo - FirstUnitTest und SecondUnitTest , mit einigen geringfügigen Unterschieden aufgrund einer anderen Version des JUnit-Frameworks, wie dem Paket für @ Test- und Assertion-Methoden.

4.2. Ausführen einer einzelnen Testklasse

Um JUnit 5-Tests mit Java-Code auszuführen, richten wir eine Instanz von LauncherDiscoveryRequest ein . Es wird eine Builder-Klasse verwendet, in der Paketauswahl- und Testklassennamenfilter festgelegt werden müssen, um alle Testklassen abzurufen, die ausgeführt werden sollen.

Diese Anforderung wird dann einem Launcher zugeordnet. Vor dem Ausführen der Tests richten wir außerdem einen Testplan und einen Ausführungslistener ein.

Beide bieten Informationen zu den auszuführenden Tests und zu den Ergebnissen:

public class RunJUnit5TestsFromJava { SummaryGeneratingListener listener = new SummaryGeneratingListener(); public void runOne() { LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() .selectors(selectClass(FirstUnitTest.class)) .build(); Launcher launcher = LauncherFactory.create(); TestPlan testPlan = launcher.discover(request); launcher.registerTestExecutionListeners(listener); launcher.execute(request); } // main method... }

4.3. Ausführen mehrerer Testklassen

Wir können Selektoren und Filter für die Anforderung festlegen, mehrere Testklassen auszuführen.

Mal sehen, wie wir Paketselektoren festlegen und Klassennamenfilter testen können, um alle Testklassen zu erhalten, die wir ausführen möchten:

public void runAll() { LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() .selectors(selectPackage("com.baeldung.junit5.runfromjava")) .filters(includeClassNamePatterns(".*Test")) .build(); Launcher launcher = LauncherFactory.create(); TestPlan testPlan = launcher.discover(request); launcher.registerTestExecutionListeners(listener); launcher.execute(request); } 

4.4. Testausgabe

In der main () -Methode rufen wir unsere Klasse auf und verwenden auch den Listener, um die Ergebnisdetails abzurufen. Dieses Mal wird das Ergebnis als TestExecutionSummary gespeichert .

Der einfachste Weg, seine Informationen zu extrahieren, besteht darin, in einen Konsolenausgabestream zu drucken:

public static void main(String[] args) { RunJUnit5TestsFromJava runner = new RunJUnit5TestsFromJava(); runner.runAll(); TestExecutionSummary summary = runner.listener.getSummary(); summary.printTo(new PrintWriter(System.out)); }

Dies gibt uns die Details unseres Testlaufs:

Test run finished after 177 ms [ 7 containers found ] [ 0 containers skipped ] [ 7 containers started ] [ 0 containers aborted ] [ 7 containers successful ] [ 0 containers failed ] [ 10 tests found ] [ 0 tests skipped ] [ 10 tests started ] [ 0 tests aborted ] [ 10 tests successful ] [ 0 tests failed ]

5. Schlussfolgerung

In diesem Artikel haben wir gezeigt, wie JUnit-Tests programmgesteuert aus Java-Code ausgeführt werden. Dabei werden JUnit 4 sowie die aktuelle JUnit 5-Version dieses Testframeworks behandelt.

Wie immer ist die Implementierung der hier gezeigten Beispiele auf GitHub sowohl für die JUnit 5-Beispiele als auch für JUnit 4 verfügbar.