Retry Failed Test in TestNG with IRetryAnalyzer
Introduction
Automated testing is a crucial part of the software development lifecycle, providing rapid feedback on the health of an application. However, dealing with failed test cases and understanding their root causes can be challenging. In this article, we'll explore how to retry failed tests in TestNG using the IRetryAnalyzer
interface. Additionally, we'll learn how to rerun all tests from scratch in a test class.
How to Retry Failed Test with IRetryAnalyzer
To implement the retry mechanism for failed tests, we'll create a separate class that implements the IRetryAnalyzer
interface. Here's an example:
package com.mystore.utility;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
public class Retry implements IRetryAnalyzer {
private static final int MAX_RETRY_COUNT = 3;
private int retryCount = 0;
@Override
public boolean retry(ITestResult result) {
if (retryCount < MAX_RETRY_COUNT) {
retryCount++;
return true;
}
return false;
}
}
In this example, the failed test cases will be retried up to three times. Adjust the maxTry
value based on your requirements.
To associate your test cases with IRetryAnalyzer
, use the retryAnalyzer
attribute in the @Test
annotation:
package com.mystore.testcases;
import org.testng.Assert;
import org.testng.annotations.Test;
public class RetryTestCase {
@Test(retryAnalyzer = Retry.class)
public void Demo1() {
System.out.println("Demo1");
Assert.assertEquals(1, 10);
}
@Test(retryAnalyzer = Retry.class)
public void Demo2() {
System.out.println("Demo2");
Assert.assertEquals(1, 10);
}
@Test(retryAnalyzer = Retry.class)
public void Demo3() {
System.out.println("Demo3");
Assert.assertEquals(1, 1);
}
@Test(retryAnalyzer = Retry.class)
public void Demo4() {
System.out.println("Demo4");
Assert.assertEquals(1, 1);
}
}
Now, the Demo1
and Demo2
methods will be retried three times, and if they continue to fail, the test execution will stop.
Using Retry Class with IAnnotationTransformer
Interface
The IAnnotationTransformer
listener allows us to modify TestNG annotations during runtime. This approach provides flexibility without requiring recompilation. Here's an example:
package com.mystore.utility;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
public class AnnotationTransformer implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
annotation.setRetryAnalyzer(Retry.class);
}
}
Add this listener to your TestNG XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="RetrySuite">
<listeners>
<listener class-name="com.mystore.utility.AnnotationTransformer"></listener>
</listeners>
<test name="RetryTest">
<classes>
<class name="com.mystore.testcases.RetryTestCase"></class>
</classes>
</test>
</suite>
Now, you can use the @Test
annotation without the retryAnalyzer
attribute in your test class:
package com.mystore.testcases;
import org.testng.Assert;
import org.testng.annotations.Test;
public class RetryTestCase {
@Test
public void Demo1() {
System.out.println("Demo1");
Assert.assertEquals(1, 10);
}
@Test
public void Demo2() {
System.out.println("Demo2");
Assert.assertEquals(1, 10);
}
@Test
public void Demo3() {
System.out.println("Demo3");
Assert.assertEquals(1, 1);
}
@Test
public void Demo4() {
System.out.println("Demo4");
Assert.assertEquals(1, 1);
}
}
Rerun All Tests in a Class When One Fails
To rerun all tests in a class when one of them fails, we'll utilize the onTestFailure
method in a custom TestListener
. Here's the relevant code snippet:
package com.mystore.utility;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.TestNG;
public class TestListener implements ITestListener{
private static int count = 0;
private final static int maxTry = 2;
public void onTestFailure(ITestResult iTestResult) {
System.out.println("I am in onTestFailure method " + iTestResult.getName() + " failed");
if (count < maxTry) {
count++;
TestNG tng = new TestNG();
tng.setDefaultTestName("RETRY TEST");
Class[] classes1 = {iTestResult.getTestClass().getRealClass()};
tng.setTestClasses(classes1);
tng.addListener(new TestListener());
tng.run();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="RetryAllSuite">
<listeners>
<listener class-name="com.mystore.utility.TestListener"></listener>
</listeners>
<test name="RetryTest">
<classes>
<class name="com.mystore.testcases.RetryTestCase"></class>
</classes>
</test>
</suite>
Now, when one of the tests fails, all tests in the class will be rerun.
Conclusion
This comprehensive approach to retrying failed tests in TestNG provides flexibility and control over your test automation suite. Choose the method that best suits your project's needs, whether it's retrying individual tests or rerunning the entire suite when needed. Happy Testing..!!