Introduction à TestNG

1. Vue d’ensemble

Dans cet article, nous allons présenter le framework de test TestNG.

Nous nous concentrerons sur: l’installation de la structure, la rédaction de scénarios de test simples, la configuration, l’exécution de tests, la génération de rapports de tests et l’exécution de tests simultanés

2. Installer

Commençons par ajouter la dépendance Maven dans notre fichier pom.xml :

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

La dernière version peut être trouvée dans Maven repository .

Lorsque vous utilisez Eclipse, le plug-in TestNG peut être téléchargé et installé à partir du site Eclipse .

3. Écrire un cas de test

Pour écrire un test en utilisant TestNG, il suffit d’annoter la méthode de test avec org.testng.annotations.Test annotation:

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

4. Configurations de test

Lors de l’écriture de scénarios de test, nous devons souvent exécuter certaines instructions de configuration ou d’initialisation avant l’exécution de tests, ainsi qu’un certain nettoyage une fois les tests terminés. TestNG fournit un certain nombre de fonctions d’initialisation et de nettoyage aux niveaux de la méthode, de la classe, du groupe et de la suite:

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

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

La méthode setup () annotée avec les annotations @ BeforeClass sera appelée avant l’exécution de toute méthode de cette classe de test et tearDown () après l’exécution de toutes les méthodes de la classe de test.

De même, nous pouvons utiliser les annotations @ BeforeMethod, @AfterMethod, @ Before/AfterGroup, @ Before/AfterTest et @ Before/AfterSuite pour toute configuration aux niveaux méthode, groupe, test et suite.

5. Test d’exécution

Nous pouvons exécuter les scénarios de test avec la commande «test» de Maven, qui exécutera tous les scénarios de test annotés avec @ Test en les plaçant dans une suite de tests par défaut. Nous pouvons également exécuter des scénarios de test à partir des fichiers XML de la suite de tests TestNG, à l’aide de l’adresse https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22% 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>

Notez que si nous avons plusieurs fichiers XML couvrant tous les cas de test, nous pouvons tous les ajouter dans la balise suiteXmlFiles :

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

Pour pouvoir exécuter le test en mode autonome, nous devons disposer de la bibliothèque TestNG dans le chemin de classe et de la classe de test compilée, ainsi que du fichier de configuration XML:

java org.testng.TestNG test__suite.xml

6. Tests de regroupement

Les tests peuvent être exécutés en groupes. Par exemple, sur 50 scénarios de test, 15 peuvent être regroupés et exécutés, laissant les autres tels quels.

Dans TestNG, les tests de regroupement en suites sont effectués à l’aide d’un fichier XML:

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

Notez que les deux classes de test RegistrationTest, SignInTest appartiennent maintenant à la même suite et qu’une fois la suite exécutée, les scénarios de test de cette classe seront exécutés.

Outre les suites de tests, nous pouvons également créer des groupes de tests dans TestNG, dans lesquels les méthodes de classes de tests sont regroupées. Pour ce faire, ajoutez le paramètre groups dans l’annotation @ Test :

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

    assertTrue(sum < 0);
}

Utilisons un XML pour exécuter les groupes:

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

Ceci exécutera la méthode de test étiquetée avec le groupe regression, dans la classe SummationServiceTest .

7. Tests paramétrés

Les tests unitaires paramétrés sont utilisés pour tester le même code dans plusieurs conditions. À l’aide de tests unitaires paramétrés, nous pouvons configurer une méthode de test permettant d’obtenir des données à partir d’une source de données. L’idée principale est de rendre la méthode de test unitaire réutilisable et de tester avec un ensemble d’entrées différent.

Dans TestNG, nous pouvons paramétrer des tests à l’aide de l’annotation @ Parameter ou @ DataProvider . Lorsque vous utilisez le fichier XML, annotez la méthode de test avec @ Parameter:

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

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

Et fournissez les données en utilisant le fichier XML:

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

Utiliser les données d’un fichier XML est utile, mais nous avons souvent besoin de données plus complexes.

L’annotation @ DataProvider est utilisée pour gérer ces scénarios, qui peuvent être utilisés pour mapper des types de paramètres complexes pour les méthodes de test . @DataProvider pour les types de données primitifs:

@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 __for objets:

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

Grâce à cela, tout objet à tester peut être créé et utilisé dans le test. Ceci est surtout utile pour les cas de test d’intégration.

8. Ignorer les cas de test

Nous voulons parfois ne pas exécuter un certain cas de test, temporairement pendant le processus de développement. Cela peut être fait en ajoutant enabled = false, dans l’annotation @ Test :

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

9. Tests dépendants

Prenons un scénario dans lequel, si le scénario de test initial échoue, tous les scénarios de test suivants doivent être exécutés et plutôt marqués comme ignorés. TestNG fournit cette fonctionnalité avec le paramètre dependsOnMethods de l’annotation @ Test :

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

Notez que le cas de test de connexion dépend du cas de test de validation de courrier électronique. Ainsi, si la validation du courrier électronique échoue, le test de connexion sera ignoré.

10. Exécution de tests simultanés

TestNG permet aux tests de s’exécuter en parallèle ou en mode multi-thread, offrant ainsi un moyen de tester ces morceaux de code multi-thread.

Vous pouvez configurer les méthodes, les classes et les suites afin qu’elles s’exécutent dans leurs propres threads, réduisant ainsi le temps d’exécution total.

10.1. Classes et méthodes en parallèle

Pour exécuter des classes de test en parallèle, mentionnez l’attribut parallel dans la balise suite du fichier de configuration XML, avec la valeur classes:

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

Notez que, si nous avons plusieurs balises test dans le fichier XML, ces tests peuvent également être exécutés en parallèle, en mentionnant parallel = "tests" . Pour exécuter également des méthodes individuelles en parallèle, mentionnez parallel = "méthodes" .

10.2. Exécution multi-thread de la méthode de test

Disons que nous devons tester le comportement d’un code lorsqu’il s’exécute dans plusieurs threads. TestNG permet d’exécuter une méthode de test dans plusieurs threads:

public class MultiThreadedTests {

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

        assertTrue(count > 1);
    }
}

ThreadPoolSize indique que la méthode sera exécutée dans le nombre n de threads indiqué. InvocationCount et timeOut indiquent que le test sera exécuté plusieurs fois et échouent s’il prend plus de temps.

11. Tests fonctionnels

TestNG est livré avec des fonctionnalités qui peuvent également être utilisées pour les tests fonctionnels. Associé à Selenium, il peut être utilisé pour tester les fonctionnalités d’une application Web ou pour tester des services Web avec HttpClient .

Plus de détails sur les tests fonctionnels avec Selenium et TestNG sont disponibles sur le lien:/java-selenium-with-junit-and-testng[ici]. Vous trouverez également d’autres éléments sur les tests d’intégration dans ce lien:/integration-testing-a-rest-api[article].

12. Conclusion

Dans cet article, nous avons brièvement expliqué comment configurer TestNG et exécuter un scénario de test simple, générer des rapports, l’exécution simultanée de scénarios de test et également un peu de programmation fonctionnelle. Pour plus de fonctionnalités telles que les tests dépendants, en ignorant les scénarios de test, les groupes de tests et les suites, vous pouvez vous référer à notre lien d’article JUnit vs TestNG:/junit-vs-testng[ici].

L’implémentation de tous les extraits de code est disponible à l’adresse over sur Github .