Introduzione a TestNG

1. Panoramica

In questo articolo, introdurremo il framework di test TestNG.

Ci concentreremo su: configurazione del framework, scrittura di test case e configurazione semplici, esecuzione di test, generazione di report di test ed esecuzione di test simultanei.

2. Configurazione

Cominciamo aggiungendo la dipendenza Maven nel nostro file pom.xml :

 org.testng testng 7.1.0 test 

L'ultima versione può essere trovata nel repository Maven.

Quando si utilizza Eclipse, il plug-in TestNG può essere scaricato e installato da Eclipse Marketplace.

3. Scrittura di un test case

Per scrivere un test utilizzando TestNG, è sufficiente annotare il metodo di test con org.testng.annotations .

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

4. Configurazioni di prova

Durante la scrittura di casi di test, spesso è necessario eseguire alcune istruzioni di configurazione o inizializzazione prima dell'esecuzione dei test e anche un po 'di pulizia dopo il completamento dei test. TestNG fornisce una serie di funzionalità di inizializzazione e pulizia a livello di metodo, classe, gruppo e suite:

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

Il metodo setup () annotato con le annotazioni @BeforeClass verrà invocato prima dell'esecuzione di qualsiasi metodo di quella classe di test e tearDown () dopo l'esecuzione di tutti i metodi della classe di test.

Allo stesso modo, possiamo utilizzare le annotazioni @BeforeMethod, @AfterMethod, @ Before / AfterGroup, @ Before / AfterTest e @ Before / AfterSuite per qualsiasi configurazione a livello di metodo, gruppo, test e suite.

5. Esecuzione del test

Possiamo eseguire i casi di test con il comando "test" di Maven, eseguirà tutti i casi di test annotati con @Test mettendoli in una suite di test predefinita. Possiamo anche eseguire casi di test dai file XML della suite di test TestNG, utilizzando il plug-in maven-surefire:

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

Tieni presente che se abbiamo più file XML, che coprono tutti i casi di test, possiamo aggiungerli tutti nel tag suiteXmlFiles :

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

Per eseguire il test standalone, abbiamo bisogno della libreria TestNG nel classpath e della classe di test compilata insieme al file di configurazione XML:

java org.testng.TestNG test_suite.xml

6. Test di raggruppamento

I test possono essere eseguiti in gruppi, ad esempio su 50 casi di test 15 possono essere raggruppati ed eseguiti lasciando gli altri così come sono.

In TestNG i test di raggruppamento nelle suite vengono eseguiti utilizzando il file XML:

Si noti che entrambe le classi di test RegistrationTest, SignInTest ora appartengono alla stessa suite e una volta eseguita la suite, i casi di test in questa classe verranno eseguiti.

Oltre alle suite di test, possiamo anche creare gruppi di test in TestNG, dove invece dei metodi delle classi di test sono raggruppati insieme. Per fare ciò, aggiungi il parametro groups nell'annotazione @Test :

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

Usiamo un XML per eseguire i gruppi:

Questo eseguirà il metodo di test contrassegnato con la regressione di gruppo , nella classe SummationServiceTest .

7. Test parametrizzati

Gli unit test parametrizzati vengono utilizzati per testare lo stesso codice in diverse condizioni. Con l'aiuto di unit test parametrizzati, possiamo impostare un metodo di test che ottiene i dati da alcune origini dati. L'idea principale è quella di rendere riutilizzabile il metodo di unit test e di testare con un diverso insieme di input.

In TestNG, possiamo parametrizzare i test usando l' annotazione @ Parameter o @DataProvider . Durante l'utilizzo del file XML annotare il metodo di test con @ Parameter:

@Test @Parameters({"value", "isEven"}) public void givenNumberFromXML_ifEvenCheckOK_thenCorrect(int value, boolean isEven) { assertEquals(isEven, value % 2 == 0); }
E fornire i dati utilizzando il file XML:

L'utilizzo di dati da file XML è utile, ma spesso abbiamo bisogno di dati più complessi. L' annotazione @DataProvider viene utilizzata per gestire questi scenari, che possono essere utilizzati per mappare tipi di parametri complessi per i metodi di test. @DataProvider per i tipi di dati primitivi:

@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 per gli oggetti:

@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)}}; }

Usando questo, qualsiasi oggetto che deve essere testato può essere creato e utilizzato nel test. Ciò è particolarmente utile per i casi di test di integrazione.

8. Ignorare i casi di test

A volte vogliamo non eseguire un certo test case, temporaneamente durante il processo di sviluppo. Questo può essere fatto aggiungendo enabled = false, nell'annotazione @ Test :

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

9. Test dipendenti

Consideriamo uno scenario in cui, se il test case iniziale fallisce, tutti i test case successivi dovrebbero essere eseguiti e piuttosto contrassegnati come ignorati. TestNG fornisce questa funzione con il dependsOnMethods parametro della @Test della nota:

@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 è dotato di funzionalità che possono essere utilizzate anche per i test funzionali. Insieme a Selenium, può essere utilizzato per testare le funzionalità di un'applicazione Web o per testare i servizi Web con HttpClient.

Maggiori dettagli sui test funzionali con Selenium e TestNG sono disponibili qui. In questo articolo anche altre informazioni sui test di integrazione.

12. Conclusione

In questo articolo, abbiamo dato una rapida occhiata a come configurare TestNG ed eseguire un semplice test case, generare report, esecuzione simultanea di test case e anche un po 'di programmazione funzionale. Per ulteriori funzionalità come test dipendenti, ignorando casi di test, gruppi di test e suite, puoi fare riferimento al nostro articolo JUnit vs TestNG qui.

L'implementazione di tutti gli snippet di codice può essere trovata su Github.