I am using TestNG for my tests. In some tests, test data gets generated so in afterMethod
I am checking if extra data was generated. If so I delete it. But sometimes for any reason data removing request doesn't return a successful response and I got an exception. In this case, all next test cases in class will be skipped. Is there a way to do not skip the remaining tests in the class if some exception was gotten in AfterMethod
? Or Is it possible to re-run skipped tests?
@AfterMethod(alwaysRun = true)
public void clearData() throws Exception {
throw new Exception();
}
@Test
public void testOne() {
//Do something
}
@Test
public void testTwo() {
//Do something
}
try-catch
would be the best solution, because any exceptions generated out of the methods should be handled by that method instead of the testng
framework.
@AfterMethod
public void clearData() throws Exception {
try{
// do something....
} catch(Exception e) {
// do nothing....
}
}
But it is possible to re-run the skipped test with a little workaround (a long one! ). (Note: I would still suggest the try-catch
approach).
Create an AfterSuite
method with alwaysRun
set to true
.
public class YourTestClass {
private static int counter = 5; //desired number of maximum retries
// all your current code.......
@AfterSuite(alwaysRun = true)
public void afterSuite(ITestContext ctx) {
IResultMap skippedTests = ctx.getSkippedTests();
while(skippedTests.size() > 0 && (counter--) > 0) {
List<XmlInclude> includeMethods
= skippedTests.getAllMethods()
.stream()
.map(m -> new XmlInclude(m.getMethodName()))
.collect(Collectors.toList());
XmlClass xmlClass = new XmlClass(this.getClass().getName());
xmlClass.setIncludedMethods(includeMethods);
XmlTest test = ctx.getCurrentXmlTest();
List<XmlClass> classes = test.getXmlClasses();
classes.remove(0);
classes.add(xmlClass);
TestRunner newRunner = new TestRunner(new Configuration(),
ctx.getSuite(),
test,
false,
null,
new ArrayList<>());
newRunner.run();
Set<String> newPassed = newRunner.getPassedTests().getAllResults()
.stream()
.map(ITestResult::getName)
.collect(Collectors.toSet());
IResultMap passedTests = ctx.getPassedTests();
Iterator<ITestResult> iter = skippedTests.getAllResults().iterator();
while(iter.hasNext()) {
ITestResult result = iter.next();
if(newPassed.contains(result.getName())) {
result.setStatus(ITestResult.SUCCESS);
passedTests.addResult(result, result.getMethod());
//remove the test from list of skipped tests.
iter.remove();
}
}
}
}
}