如何在 testNG 中重新运行跳过的测试?

How to rerun skipped tests in testNG?

我正在使用 TestNG 进行测试。在某些测试中,会生成测试数据,因此在 afterMethod 中,我正在检查是否生成了额外数据。如果是这样我删除它。但有时出于任何原因,数据删除请求没有 return 成功响应,我得到了一个例外。在这种情况下,class 中的所有下一个测试用例都将被 跳过 。如果在 AfterMethod 中出现异常,有没有办法不跳过 class 中的剩余测试?或者是否可以重新运行 跳过的测试?

@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 将是最好的解决方案,因为任何由方法生成的异常都应该由该方法而不是 testng 框架处理。

@AfterMethod
public void clearData() throws Exception {
    try{
        // do something....
    } catch(Exception e) {
        // do nothing....
    }
}

但是可以通过 变通方法 重新运行 跳过的测试(很长!)。 (注意:我仍然建议使用 try-catch 方法)。

创建 AfterSuite 方法并将 alwaysRun 设置为 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();
                }
            }     
        }
    }
}