Einführung in TestNG

1. Überblick

In diesem Artikel stellen wir das TestNG-Testframework vor.

Wir konzentrieren uns auf: Framework-Setup, einfache Testfälle und -Konfiguration schreiben, Testausführung, Testberichterstellung und gleichzeitige Testausführung.

2. Konfiguration

Beginnen wir mit dem Hinzufügen der Maven-Abhängigkeit in unserer pom.xml -Datei:

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.11</version>
    <scope>test</scope>
</dependency>

Die neueste Version finden Sie unter Maven-Repository .

Wenn Sie Eclipse verwenden, kann das TestNG-Plugin von Eclipse Marketplace heruntergeladen und installiert werden.

3. Testfall schreiben

Um einen Test mit TestNG zu schreiben, müssen Sie nur die Testmethode mit org.testng.annotations.Test annotation kommentieren:

@Test
public void givenNumber__whenEven__thenTrue() {
    assertTrue(number % 2 == 0);
}

4. Testkonfigurationen

Beim Schreiben von Testfällen müssen häufig einige Konfigurations- oder Initialisierungsanweisungen vor der Testausführung und einige Bereinigungen nach Abschluss der Tests ausgeführt werden. TestNG bietet eine Reihe von Initialisierungs- und Bereinigungsfunktionen auf Methoden-, Klassen-, Gruppen- und Suiteebene:

@BeforeClass
public void setup() {
    number = 12;
}

@AfterClass
public void tearDown() {
    number = 0;
}

Die setup () -Methode, die mit @ BeforeClass -Annotationen versehen ist, wird vor der Ausführung von Methoden dieser Testklasse und tearDown () nach der Ausführung aller Methoden der Testklasse aufgerufen.

Auf ähnliche Weise können wir die Annotationen @ BeforeMethod, @AfterMethod, @ Before/AfterGroup, @ Before/AfterTest und @ Before/AfterSuite für jede Konfiguration auf Methoden-, Gruppen-, Test- und Suite-Ebene verwenden.

5. Test Ausführung

Wir können die Testfälle mit dem "test" -Befehl von Maven ausführen. Er führt alle Testfälle aus, die mit @ Test kommentiert wurden, und versetzen sie in eine Standard-Testsuite. Wir können Testfälle auch aus den XML-Dateien der TestNG-Testsuite ausführen, indem Sie https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22% verwenden. 20AND% 20a% 3A% 22maven-surefire-plugin% 22[maven-surefire-plugin]:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <suiteXmlFiles>
            <suiteXmlFile>
               src\test\resources\test__suite.xml
            </suiteXmlFile>
        </suiteXmlFiles>
    </configuration>
</plugin>

Wenn Sie über mehrere XML-Dateien verfügen, die alle Testfälle abdecken, können Sie alle im suiteXmlFiles -Tag hinzufügen:

<suiteXmlFiles>
    <suiteXmlFile>
      src/test/resources/parametrized__test.xml
    </suiteXmlFile>
    <suiteXmlFile>
      src/test/resources/registration__test.xml
    </suiteXmlFile>
</suiteXmlFiles>

Um den Test Standalone auszuführen, benötigen wir die TestNG-Bibliothek im Klassenpfad und die kompilierte Testklasse zusammen mit der XML-Konfigurationsdatei:

java org.testng.TestNG test__suite.xml

6. Gruppentests

Tests können in Gruppen ausgeführt werden, z. B. kann aus 50 Testfällen 15 zusammen gruppiert und ausgeführt werden, wobei die anderen unverändert bleiben.

In TestNG werden Gruppierungen in Suites mit XML-Dateien durchgeführt:

<suite name="suite">
    <test name="test suite">
        <classes>
            <class name="com.baeldung.RegistrationTest"/>
            <class name="com.baeldung.SignInTest"/>
        </classes>
    </test>
</suite>

Beachten Sie, dass die beiden Testklassen RegistrationTest, SignInTest jetzt zur selben Suite gehören. Sobald die Suite ausgeführt wird, werden Testfälle in dieser Klasse ausgeführt.

Neben Test-Suites können in TestNG auch Testgruppen erstellt werden, in denen anstelle von Testklassen Methoden gruppiert werden. Fügen Sie dazu den groups -Parameter in der Annotation @ Test hinzu:

@Test(groups = "regression")
public void givenNegativeNumber__sumLessthanZero__thenCorrect() {
    int sum = numbers.stream().reduce(0, Integer::sum);

    assertTrue(sum < 0);
}

Verwenden wir zum Ausführen der Gruppen ein XML:

<test name="test groups">
    <groups>
        <run>
            <include name="regression"/>
        </run>
    </groups>
    <classes>
        <class
          name="com.baeldung.SummationServiceTest"/>
    </classes>
</test>

Dadurch wird die mit group regression, gekennzeichnete Testmethode in der Klasse SummationServiceTest ausgeführt.

7. Parametrisierte Tests

Parametrisierte Unit-Tests werden zum Testen desselben Codes unter mehreren Bedingungen verwendet. Mit Hilfe parametrisierter Unit-Tests können wir eine Testmethode einrichten, die Daten aus einer Datenquelle bezieht. Die Hauptidee besteht darin, die Komponententestmethode wiederverwendbar zu machen und mit einem anderen Eingangssatz zu testen.

In TestNG können Tests mithilfe der Annotation @ Parameter oder @ DataProvider parametrisiert werden. Bei Verwendung der XML-Datei kommentieren Sie die Testmethode mit @ Parameter:

@Test
@Parameters({"value", "isEven"})
public void
  givenNumberFromXML__ifEvenCheckOK__thenCorrect(int value, boolean isEven) {

    assertEquals(isEven, value % 2 == 0);
}

Und stellen Sie die Daten mithilfe einer XML-Datei bereit:

<suite name="My test suite">
    <test name="numbersXML">
        <parameter name="value" value="1"/>
        <parameter name="isEven" value="false"/>
        <classes>
            <class name="baeldung.com.ParametrizedTests"/>
        </classes>
    </test>
</suite>

Die Verwendung von Daten aus einer XML-Datei ist hilfreich, aber häufig benötigen wir komplexere Daten.

Die Annotation @ DataProvider wird zum Behandeln dieser Szenarien verwendet, die zum Zuordnen komplexer Parametertypen für Testmethoden verwendet werden können. @DataProvider für primitive Datentypen:

@DataProvider(name = "numbers")
public static Object[][]evenNumbers() {
    return new Object[][]{{1, false}, {2, true}, {4, true}};
}

@Test(dataProvider = "numbers")
public void
  givenNumberFromDataProvider__ifEvenCheckOK__thenCorrect(Integer number, boolean expected) {
    assertEquals(expected, number % 2 == 0);
}

__ @ DataProvider __für Objekte:

@Test(dataProvider = "numbersObject")
public void
  givenNumberObjectFromDataProvider__ifEvenCheckOK__thenCorrect(EvenNumber number) {
    assertEquals(number.isEven(), number.getValue() % 2 == 0);
}

@DataProvider(name = "numbersObject")
public Object[][]parameterProvider() {
    return new Object[][]{{new EvenNumber(1, false)},
      {new EvenNumber(2, true)}, {new EvenNumber(4, true)}};
}

Damit kann jedes Objekt, das getestet werden muss, erstellt und im Test verwendet werden. Dies ist vor allem für Integrationstestfälle hilfreich.

8. Testfälle ignorieren

Manchmal möchten wir einen bestimmten Testfall vorübergehend während des Entwicklungsprozesses nicht ausführen. Dies kann durch Hinzufügen von enabled = false, in der Annotation @ Test erfolgen:

@Test(enabled=false)
public void givenNumbers__sumEquals__thenCorrect() {
    int sum = numbers.stream.reduce(0, Integer::sum);
    assertEquals(6, sum);
}

9. Abhängige Tests

Betrachten wir ein Szenario, in dem, wenn der ursprüngliche Testfall fehlschlägt, alle nachfolgenden Testfälle ausgeführt und als übersprungen gekennzeichnet werden sollen. TestNG stellt diese Funktion mit dem dependsOnMethods -Parameter der @ Test -Annotation bereit:

@Test
public void givenEmail__ifValid__thenTrue() {
    boolean valid = email.contains("@");

    assertEquals(valid, true);
}

@Test(dependsOnMethods = {"givenEmail__ifValid__thenTrue"})
public void givenValidEmail__whenLoggedIn__thenTrue() {
    LOGGER.info("Email {} valid >> logging in", email);
}

Beachten Sie, dass der Login-Testfall vom Testfall der E-Mail-Validierung abhängt. Wenn die E-Mail-Überprüfung fehlschlägt, wird der Login-Test übersprungen.

10. Gleichzeitige Testdurchführung

Mit TestNG können Tests parallel oder im Multithreading-Modus ausgeführt werden, wodurch diese Codeteile mit mehreren Threads getestet werden können.

Sie können konfigurieren, dass Methoden, Klassen und Suites in ihren eigenen Threads ausgeführt werden, wodurch die Gesamtausführungszeit reduziert wird.

10.1. Parallele Klassen und Methoden

Um Testklassen parallel auszuführen, geben Sie das parallel -Attribut im Tag suite in der XML-Konfigurationsdatei mit dem Wert classes an:

<suite name="suite" parallel="classes" thread-count="2">
    <test name="test suite">
        <classes>
        <class name="baeldung.com.RegistrationTest"/>
            <class name="baeldung.com.SignInTest"/>
        </classes>
    </test>
</suite>

Wenn sich in der XML-Datei mehrere test -Tags befinden, können diese Tests auch parallel ausgeführt werden, indem __parallel = "tests" erwähnt wird.

10.2. Multi-Threaded-Ausführung der Testmethode

Angenommen, wir müssen das Verhalten eines Codes testen, wenn er in mehreren Threads ausgeführt wird. Mit TestNG können Sie eine Testmethode in mehreren Threads ausführen:

public class MultiThreadedTests {

    @Test(threadPoolSize = 5, invocationCount = 10, timeOut = 1000)
    public void givenMethod__whenRunInThreads__thenCorrect() {
        int count = Thread.activeCount();

        assertTrue(count > 1);
    }
}

Das threadPoolSize gibt an, dass die Methode in n Anzahl der Threads ausgeführt wird. InvocationCount und timeOut zeigen an, dass der Test mehrmals ausgeführt wird, und der Test schlägt fehl, wenn er länger dauert.

11. Funktionstest

TestNG verfügt über Funktionen, die auch für Funktionsprüfungen verwendet werden können. In Verbindung mit Selenium kann es entweder zum Testen der Funktionalität einer Webanwendung oder zum Testen von Webdiensten mit HttpClient verwendet werden.

Weitere Einzelheiten zur Funktionsprüfung mit Selenium und TestNG finden Sie unter:/Java-Selenium mit Junit-and-Testng[hier]. Weitere Informationen zu Integrationstests finden Sie in diesem Link:/integration-testing-a-rest-api[Artikel].

12. Schlussfolgerung

In diesem Artikel wurde kurz beschrieben, wie TestNG eingerichtet und ein einfacher Testfall ausgeführt wird, Berichte erstellt werden, Testfälle gleichzeitig ausgeführt werden und ein wenig zur funktionalen Programmierung beschrieben wird. Weitere Funktionen wie abhängige Tests, das Ignorieren von Testfällen, Testgruppen und Suites finden Sie in unserem Artikel zu JUnit vs. TestNG:/junit-vs-testng[hier].

Die Implementierung aller Code-Snippets finden Sie unter über Github .