If I run the tests on the version testng 6.14.3, then the dropped tests are restarted. If I run the tests on the version testng 7.0.0, then the dropped tests aren't restarted.
public class RetryAnalyzer implements IRetryAnalyzer {
private int count = 0;
private static int maxTry = 2;
@Override public boolean retry(ITestResult iTestResult) {
if (!iTestResult.isSuccess()) {
if (count < maxTry) {
count++;
iTestResult.setStatus(ITestResult.FAILURE);
iTestResult.getTestContext().getFailedTests().removeResult(iTestResult);
return true;
} else {
iTestResult
.setStatus(ITestResult.FAILURE);
}
} else {
iTestResult
.setStatus(ITestResult.SUCCESS);
}
return false;
}
}
public class AnnotationTransformer implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor,
Method testMethod) {
annotation.setRetryAnalyzer(RetryAnalyzer.class);
}
}
My listener:
<listeners>
<listener class-name="package.AnnotationTransformer"/>
</listeners>
I have tried your implementation and it perfectly works for me (used TestNG 7.0.0). Ensure that imports and class-paths are correct (double-check <listener class-name="package.AnnotationTransformer"/>
)`.
Also, consider the following, please:
boolean retry()
method of IRetryAnalyzer
interface. The logic of returning a result (a boolean) dependent on the counter is already defined by TestNG RetryAnalyzerCount
class (it also implements IRetryAnalyzer
interface). Thus, it is better to re-use the code of RetryAnalyzerCount
(with the same logic as yours): a) by setting the count for maximum retry attempts from within RetryAnalyzer
class and
b) by overriding abstract boolean retryMethod(ITestResult var1);
from TestNG RetryAnalyzerCount
class, which returns a positive boolean result ( true
) if a test failed.
import java.util.concurrent.atomic.AtomicInteger;
import org.testng.ITestResult;
import org.testng.util.RetryAnalyzerCount;
import lombok.extern.slf4j.Slf4j;
/**
* Used by RetryListener (or AnnotationTransformer) to avoid the declaration of 'retryAnalyzer' in each @Test annotation
*/
@Slf4j
public class RetryAnalyzer extends RetryAnalyzerCount {
private static final int MAX_RETRY_ATTEMPTS = 3;
private AtomicInteger counter = new AtomicInteger(1); //used only for logging purposes
public RetryAnalyzer() {
setCount(MAX_RETRY_ATTEMPTS);
}
@Override
public boolean retryMethod(ITestResult result) {
// log example: [15/04/20 13:31] WARN [RetryAnalyzer] RETRY failed test 'displaySearchResultForValidInput' (1 out of 3 times)
String methodName = result.getMethod().getMethodName();
log.warn("RETRY failed test '{}' ({} out of {} times)",
methodName,
this.counter.getAndIncrement(),
MAX_RETRY_ATTEMPTS);
// enough is only the return statement
return true;
}
}
AnnotationTransformer
as it is.<listeners>
tag in TestNG .xml
file includes correct path to the listener ( AnnotationTransformer
).OR simplify everything:
a) by deleting AnnotationTransformer
and <listeners>
from TestNG .xml
file and
b) by setting custom RetryAnalyzer
for TestNG in @BeforeSuite
(!!! not @BeforeMethod
, which leads to an infinite loop)
@BeforeSuite
void beforeSuiteSetUp(ITestContext testsContext) {
setCustomRetryAnalyzer(testsContext);
}
private void setCustomRetryAnalyzer(ITestContext testsContext) {
for (ITestNGMethod method : testsContext.getAllTestMethods()) {
method.setRetryAnalyzerClass(RetryAnalyzer.class);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.