Ip Man
Ip Man

Reputation: 77

How to rerun skipped tests in testNG?

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
}

Upvotes: 1

Views: 1281

Answers (1)

Gautham M
Gautham M

Reputation: 4935

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();
                }
            }     
        }
    }
}

Upvotes: 1

Related Questions