Reputation: 393
Hello: When a @Test fails
and a Retry
happens, is there a direct way in TestNG to distinguish between a Test that has been Retried and a test that has not been retried - such as through a NG context method or variable?
1st test
is a test that has not been retried.3rd test
is a test that has not been retried.Some options i have found such as http://www.seleniumeasy.com/testng-tutorials/retry-listener-failed-tests-count-update - but wanted to check if the community has other means and/or recommendations.
Upvotes: 0
Views: 1220
Reputation: 14746
You can try something like this. The idea is to basically retrieve the retry analyser instance associated with a particular test method and then query its retry count. If its retry count was greater than zero, then that method was retried.
import org.testng.Assert;
import org.testng.IRetryAnalyzer;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
@Listeners(IdentifyRetriedTests.IdentifyingListener.class)
public class IdentifyRetriedTests {
private static AtomicInteger counter = new AtomicInteger(0);
private static AtomicInteger anotherCounter = new AtomicInteger(0);
@Test(retryAnalyzer = Retry.class)
public void hello() {
if (counter.incrementAndGet() == 3) {
Assert.assertTrue(true);
} else {
Assert.fail();
}
}
@Test(retryAnalyzer = Retry.class)
public void anotherHello() {
if (anotherCounter.incrementAndGet() == 5) {
Assert.assertTrue(true);
} else {
Assert.fail();
}
}
public static class IdentifyingListener extends TestListenerAdapter {
@Override
public void onTestSuccess(ITestResult tr) {
IRetryAnalyzer retry = tr.getMethod().getRetryAnalyzer();
if (retry instanceof Retry) {
//Check if the retry analyser's retry count was greater than zero. If yes, then its a retried method
if (((Retry) retry).getRetryCount() > 0) {
tr.setAttribute("retried", true);
}
}
}
@Override
public void onFinish(ITestContext testContext) {
Set<ITestResult> results = new HashSet<>();
results.addAll(testContext.getFailedTests().getAllResults());
results.addAll(testContext.getPassedTests().getAllResults());
for (ITestResult result : results) {
if (result.getAttribute("retried") != null) {
System.err.println(result.getMethod().getMethodName() + "() was retried");
}
}
}
}
public static class Retry implements IRetryAnalyzer {
private AtomicInteger retryCount = new AtomicInteger(0);
private static int maxRetryCount = 10;
public boolean retry(ITestResult result) {
return retryCount.getAndIncrement() < maxRetryCount;
}
int getRetryCount() {
return retryCount.get();
}
}
}
Upvotes: 2
Reputation: 5740
Currently, there is no easy way to know if the test is a retry or not.
Maybe you can to collect every run methods in a testng listener, and then you can determine if the method was retried if you already find it in the list of run methods.
BTW, you should ask for the feature on http://github.com/cbeust/testng/issues
Upvotes: 1