Tests et TestNG

Fonctionnalités de TestNG

Regroupement de tests

TestNG nous permet de regrouper les tests par groupe. De plus un groupe de tests peut être inclus dans un autre groupe de tests. Voici un exemple de comment utiliser cela :

public class TestAvecGroupes {
  @Test(groups = { "nonregression", "unit" })
  public void testMethod1() {
  } 
 
  @Test(groups = { "unit" })
  public void testMethod2() {
  }
}      

Pour lancer cet exemple, nous pouvons écrire cela dans le fichier testng.xml:

<test name="TestAvecGroupes">
  <groups>
    <run>
      <include name="nonregression">
    </include></run>
  </groups>
  <classes>
    <class name="univ.mlv.fr.xpose.tests.TestAvecGroupes">
  </class></classes>
</test>

Dans ce fichier testng.xml nous avons fait le choix de ne lancer que les tests correspondants au groupe "nonregression".

Parallélisation du lancement des tests

TestNG nous permet également quelque chose de vraiment intéressant par rapport à JUnit, qui permet d'augmenter les performances. En effet testNG a mis à disposition des utilisateurs des méthodes pour lancer en paralléle plusieurs tests, grâce au procédé du multi-threading. Bien sûr comme je l'ai déjà dit précédemment, ce procédé est threadsafe, il n'y a pas de problème de concurrence généré par cette utilisation. Il existe deux manières de paralléliser du code de test:

Une fois que nous avons lancé nos tests il est possible de regarder s'ils se sont bien lancés en paralléle grâce à cela:

Ici nous voyons qu'un seul et unique thread a lancé tous les tests (de manière séquencielle donc). Maintenant, si nous choisissons d'utiliser le parrallélisme cela donne: en écrivant cela dans le code de test:

@Test(dataProvider = "creerLivre", threadPoolSize = 3, invocationCount = 3, timeOut = 10000)
    public void testAjoutNonRedondant(String n1, Livre l) {
		Bibliotheque biblio = new Bibliotheque();
		System.out.println("ajout de: " + l);
		Assert.assertEquals(true, GestionBiblio.ajouterLivre(l, biblio));
	}
Nous obtenons:

Nous voyons bien que les tests testAjoutNonRedondant sont lancés par plusieurs threads

Génération dynamique de tests

TestNG nous permet également de générer dynamiquement des tests, pour illustrer cela, je vais reprendre un exemple fourni dans la documentation de testNG qui me semble très parlant:

Imaginez que vous vouliez tester une interface web N fois avec des valeurs différentes:

//factory
public class WebTestFactory {
  @Factory
  public Object[] createInstances() {
   Object[] result = new Object[10]; 
   for (int i = 0; i < 10; i++) {
      result[i] = new WebTest(i * 10);
    return result;
  }
}

//class test utilsant la factory
public class WebTest {
  private int m_numberOfTimes;
  public WebTest(int numberOfTimes) {
    m_numberOfTimes = numberOfTimes;
  }
 
  @Test
  public void testServer() {
   for (int i = 0; i < m_numberOfTimes; i++) {
     // access the web page
    }
  }
}       
          

Cet exemple nous montre très clairement qu'il nous sera beaucoup plus aisé de faire tous les tests voulus grâce à la factory plutôt qu'en les écrivant tous un par un.

Relancer les tests sortis en erreur

TestNG nous permet de choisir de ne relancer que les tests qui sont sortis en erreur, pour ce faire nous pouvons utiliser la ligne de commande de la manière suivante:

java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -d test-outputs testng.xml
java -classpath testng.jar;%CLASSPATH% org.testng.TestNG -d test-outputs test-outputs\testng-failed.xml