JUnit testet programmgesteuert von einer Java-Anwendung aus

Programmgesteuertes Ausführen von JUnit-Tests aus einer Java-Anwendung

1. Überblick

In diesem Tutorial zeigen wirhow to run JUnit tests directly from Java code - 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 dermany tutorials überprüfen, die wir zu diesem Thema haben.

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 vonJUnit 4,JUnit 5 undJUnit 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 die Annotation@Testhinzufügen.

Wir können auch andere nützliche Anmerkungen hinzufügen, z. B.@Before oder@After. Dies ist jedoch nicht Gegenstand dieses Lernprogramms.

3.2. Ausführen einer einzelnen Testklasse

Um JUnit-Tests mit Java-Code auszuführen, können Sie die KlasseJUnitCore verwenden (mit einem Zusatz der KlasseTextListener, mit der die Ausgabe inSystem.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 wirto specify multiple test classes mit JUnit 4 wollen, 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 derResult-Klasse 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 wirTestSuite erstellen. Dies ist nur eine leere Klasse, in der wir alle Klassen mit 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

Eines der interessanten Merkmale von JUnit ist, dass wirrepeat tests by creating instances of RepeatedTest können. 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 fünfmal vonMergeListsTest 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 wirJUnit4TestAdapter 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 vorherigen Demos -FirstUnitTest undSecondUnitTest, mit einigen geringfügigen Unterschieden aufgrund einer anderen Version des JUnit-Frameworks, wie dem Paket für@Test und Assertionsmethoden.

4.2. Ausführen einer einzelnen Testklasse

Um JUnit 5-Tests mit Java-Code auszuführen, richten wir eine Instanz vonLauncherDiscoveryRequest ein. Es wird eine Builder-Klasse verwendet, in der wir Paketselektoren und Testklassennamenfilter festlegen müssen, um alle Testklassen abzurufen, die wir ausführen möchten.

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 durchzuführenden Tests und 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, um mehrere Testklassen auszuführen.

Lassen Sie uns sehen, wie wir Paketauswahl- und Testklassennamenfilter festlegen können, um alle Testklassen abzurufen, die wir ausführen möchten:

public void runAll() {
    LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
      .selectors(selectPackage("com.example.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 dermain()-Methode rufen wir unsere Klasse auf und verwenden auch den Listener, um die Ergebnisdetails abzurufen. Dieses Mal wird das Ergebnis alsTestExecutionSummary gespeichert.

Die einfachste Möglichkeit, Informationen zu extrahieren, besteht darin, sie 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 wird uns die Details unseres Testlaufs geben:

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. Fazit

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ürJUnit 5 examples als auch fürJUnit 4 verfügbar.