Réexécution des tests ayant échoué dans TestNG

Réexécution des tests ayant échoué dans TestNG
MIN
18 Mar 2024

Dans cet article, nous allons apprendre à rejouer les cas de test qui ont échoué en utilisant TestNG. Nous explorerons deux approches pour y parvenir, à savoir l’utilisation du fichier testng-failed.xml et l’implémentation de l’IRetryAnalyzer de TestNG.

Table des matières

Redémarrez les tests qui ont échoué en utilisant le fichier testng-failed.xml

Quand l’utiliser ?

Parfois, en tant que testeurs de l’automatisation des tests, il nous est seulement demandé d’exécuter les tests défaillants signalés par l’outil d’automatisation des tests après avoir corrigé certains bogues. Le fait de n’exécuter que les tests qui ont échoué permet de vérifier rapidement les corrections de bogues.

Comment y parvenir ?

Il est relativement facile de n’exécuter que les tests qui ont échoué, car TestNG fournit un support naturel pour cela. Lorsqu’une suite de tests est exécutée à l’aide du fichier testng.xml, le fichier testng-failed.xml est créé dans le dossier test-output après l’exécution du test. Plus tard, nous pourrons exécuter ce fichier tout comme le fichier testng.xml. Étant donné que ce fichier ne stocke que les tests qui ont échoué, l’exécution de ce fichier n’entraînera que l’exécution des tests qui ont échoué.

Réessai automatique des tests ayant échoué avec IRetryAnalyzer

Quand l’utiliser ?

Parfois, des échecs qui ne sont pas dus à des problèmes dans l’application apparaissent dans le rapport d’exécution du test. La cause première de ces problèmes peut être liée à la configuration de l’environnement de test ou à un problème occasionnel du serveur. Pour s’assurer que les échecs signalés dans le rapport de test sont réels et qu’il ne s’agit pas de cas isolés, nous pouvons réexécuter les cas de test qui ont échoué afin d’éliminer les résultats de test faussement négatifs dans les rapports de test.

Comment y parvenir ?

Pour réessayer automatiquement les cas de test qui ont échoué pendant l’exécution du test, nous devons implémenter l’interface IRetryAnalyzer fournie par TestNG. L’interface IRetryAnalyzer fournit des méthodes pour contrôler la répétition des tests. Nous allons surcharger la méthode retry() de IRetryAnalyzer pour nous assurer que le test est exécuté en cas d’échec avec la limite de répétition spécifiée. Grâce aux commentaires de l’extrait, c’est compréhensible.

Extrait

package com.artoftesting.test;

import org.testng.IRetryAnalyzer;

import org.testng.ITestResult;

public class RetryAnalyzer implements IRetryAnalyzer {

 //Counter to keep track of retry attempts

 int retryAttemptsCounter = 0;

 //The max limit to retry running of failed test cases

 //Set the value to the number of times we want to retry

 int maxRetryLimit = 1;

 //Method to attempt retries for failure tests

 public boolean retry(ITestResult result) {

 if (!result.isSuccess()) {

 if(retryAttemptsCounter < maxRetryLimit){

 retryAttemptsCounter++;

 return true;

 }

 }

 return false;

 } 

}

Dans l’exemple, nous allons créer une méthode de test factice et la faire échouer intentionnellement en utilisant la méthode assert.fail(). Ici, nous définissons l’attribut retryAnalyzer de l’annotation @Test en utilisant la classe RetryAnalyzer.class que nous avons créée ci-dessus.

@Test(retryAnalyzer = RetryAnalyzer.class)

    public void intentionallyFailingTest(){

     System.out.println("Executing Test");

     Assert.fail("Failing Test");

    }

Sortie d’essai

===============================================

Suite de tests

Total des tests exécutés : 2, Échecs : 1, Sauts : 1

===============================================

Ici, nous pouvons observer que le nombre d’exécutions de la méthode est de 2, avec un échec et un saut. La première fois que la méthode de test échoue, elle est marquée comme étant ignorée, puis le test s’exécute à nouveau grâce à la logique fournie par RetryAnalyzer.

Il ne reste plus qu’un problème : nous devons définir l’attribut retryAnalyzer dans chaque annotation @Test. Pour y remédier, nous pouvons mettre en œuvre l’interface IAnnotationTransformer. Cette interface permet de modifier l’annotation testNG à la volée. Nous créons donc une classe implémentant l’interface IAnnotationTransformer et lui faisons définir RetryAnalyzer pour les annotations @Test.

package com.ittester.test;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

import org.testng.IAnnotationTransformer;

import org.testng.IRetryAnalyzer;

import org.testng.annotations.ITestAnnotation;

public class FailureRetryListener implements IAnnotationTransformer {

 //Overriding the transform method to set the RetryAnalyzer

 public void transform(ITestAnnotation testAnnotation, Class testClass, 

 Constructor testConstructor, Method testMethod) {

 IRetryAnalyzer retry = testAnnotation.getRetryAnalyzer();

 if (retry == null)

 testAnnotation.setRetryAnalyzer(RetryAnalyzer.class);

 }

}

Une fois le listener créé, nous pouvons le spécifier dans le fichier testNG.xml comme suit

<listeners>

   <listener class-name="com.ittester.test.FailureRetryListener"/>

</listeners>

Désormais, nous n’avons plus besoin de définir retryAnalyzer dans chaque annotation @Test. Si un auditeur est spécifié dans le fichier testng.xml, il fonctionnera pour tous les tests.

PS : Si vous souhaitez ajouter la fonctionnalité de réessai uniquement à un ensemble limité de méthodes de test, il vous suffit de définir l’annotation @Test avec l’attribut retryAnalyzer en utilisant la classe RetryAnalyzer.class, il n’est pas nécessaire d’implémenter IAnnotationTransformer et d’ajouter un écouteur dans le fichier testng.xml.