Einführung in TestNG

1. Übersicht

In diesem Artikel stellen wir das TestNG-Testframework vor.

Wir konzentrieren uns auf: Framework-Einrichtung, Schreiben eines einfachen Testfalls und Konfiguration, Testausführung, Generierung von Testberichten und gleichzeitige Testausführung.

2. Setup

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

 org.testng testng 7.1.0 test 

Die neueste Version finden Sie im Maven-Repository.

Bei Verwendung von Eclipse kann das TestNG-Plugin vom Eclipse Marketplace heruntergeladen und installiert werden.

3. Schreiben eines Testfalls

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

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

4. Konfigurationen testen

Beim Schreiben von Testfällen müssen wir häufig einige Konfigurations- oder Initialisierungsanweisungen vor der Testausführung und auch einige Bereinigungen nach Abschluss der Tests ausführen. TestNG bietet eine Reihe von Initialisierungs- und Bereinigungsfunktionen auf Methoden-, Klassen-, Gruppen- und Suite-Ebene:

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

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

In ähnlicher 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. Testausführung

Wir können die Testfälle mit Mavens Befehl "test" ausführen. Er führt alle Testfälle aus, die mit @Test kommentiert sind, und fügt sie einer Standard-Testsuite hinzu. Mit dem Maven-Surefire-Plugin können wir auch Testfälle aus den XML-Dateien der TestNG-Testsuite ausführen:

 org.apache.maven.plugins maven-surefire-plugin 2.19.1    src\test\resources\test_suite.xml    

Beachten Sie, dass wir bei mehreren XML-Dateien, die alle Testfälle abdecken, alle im suiteXmlFiles- Tag hinzufügen können :

  src/test/resources/parametrized_test.xml   src/test/resources/registration_test.xml  

Um den Test eigenständig ausführen zu können, müssen die TestNG-Bibliothek im Klassenpfad und die kompilierte Testklasse zusammen mit der XML-Konfigurationsdatei vorhanden sein:

java org.testng.TestNG test_suite.xml

6. Gruppierungstests

Tests können in Gruppen ausgeführt werden. Beispielsweise können von 50 Testfällen 15 zusammengefasst und ausgeführt werden, wobei andere unverändert bleiben.

In TestNG werden Gruppierungstests in Suiten mithilfe einer XML-Datei durchgeführt:

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

Neben Testsuiten können wir in TestNG auch Testgruppen erstellen, in denen anstelle von Testklassen Methoden zusammengefasst werden. Fügen Sie dazu den Parameter groups in die Annotation @Test ein :

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

Verwenden wir ein XML, um die Gruppen auszuführen:

Dies wird die Testmethode getaggt mit Gruppe ausführen Regression, in der SummationServiceTest Klasse.

7. Parametrisierte Tests

Parametrisierte Komponententests werden verwendet, um denselben Code unter verschiedenen Bedingungen zu testen. Mit Hilfe parametrisierter Komponententests können wir eine Testmethode einrichten, die Daten aus einer Datenquelle erhält. Die Hauptidee besteht darin, die Unit-Test-Methode wiederverwendbar zu machen und mit einem anderen Satz von Eingaben zu testen.

In TestNG können wir Tests mithilfe der Annotation @ Parameter oder @DataProvider parametrisieren . Kommentieren Sie bei Verwendung der XML-Datei 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:

Die Verwendung von Daten aus einer XML-Datei ist nützlich, wir benötigen jedoch häufig komplexere Daten. Die @ DataProvider- Annotation wird verwendet, um diese Szenarien zu behandeln, mit denen komplexe Parametertypen für Testmethoden zugeordnet 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 zu testende Objekt erstellt und im Test verwendet werden. Dies ist vor allem für Integrationstestfälle nützlich.

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 erste Testfall fehlschlägt, alle nachfolgenden Testfälle ausgeführt und eher als übersprungen markiert werden sollten. TestNG stellt diese Funktion mit dem Parameter abhängige Methoden 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); }

Notice that, the login test case depends on the email validation test case. Thus, if email validation fails the login test will be skipped.

10. Concurrent Test Execution

TestNG allows tests to run in parallel or in multi-threaded mode, thus providing a way to test these multi-threaded pieces of code.

You can configure, for methods, classes, and suites to run in their own threads reducing the total execution time.

10.1. Classes and Methods in Parallel

To run test classes in parallel, mention the parallel attribute in the suite tag in XML configuration file, with value classes:

Note that, if we have multiple test tags in the XML file, these tests can also be run in parallel, by mentioning parallel =” tests”. Also to execute individual methods in parallel, mention parallel =” methods”.

10.2. Multi-Threaded Execution of Test Method

Let's say we need to test the behavior of a code when running in multiple threads. TestNG allows to run a test method in multiple threads:

public class MultiThreadedTests { @Test(threadPoolSize = 5, invocationCount = 10, timeOut = 1000) public void givenMethod_whenRunInThreads_thenCorrect() { int count = Thread.activeCount(); assertTrue(count > 1); } }

The threadPoolSize indicates that the method will run in n number of threads as mentioned. The invocationCount and timeOut indicate that the test will be executed multiple times and fail the test if it takes more time.

11. Functional Testing

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

Weitere Details zu Funktionstests mit Selen und TestNG finden Sie hier. In diesem Artikel finden Sie auch einige weitere Informationen zum Integrationstest.

12. Schlussfolgerung

In diesem Artikel haben wir uns kurz mit dem Einrichten von TestNG und dem Ausführen eines einfachen Testfalls, dem Generieren von Berichten, der gleichzeitigen Ausführung von Testfällen und ein wenig mit der funktionalen Programmierung befasst. Weitere Funktionen wie abhängige Tests, Ignorieren von Testfällen, Testgruppen und Suites finden Sie in unserem Artikel JUnit vs TestNG hier.

Die Implementierung aller Codefragmente finden Sie auf Github.