当前位置: 首页 > 知识库问答 >
问题:

TestNG重试失败的测试不会输出正确的测试结果

花稳
2023-03-14

安装程序:我有一个扩展IRetryAnalyzer的类,并实现了一个简单的重试逻辑,覆盖了以下方法:public boolean retry(ITestResult result){

提前道谢。

共有1个答案

邹嘉致
2023-03-14

请考虑以下与MAX的测试结果。2次重试:

  1. 通过=>总体确定!
  2. 失败,通过=>总体确定!
  3. 失败,失败,通过=>总体确定!
  4. 失败,失败,失败=>整体失败!

我所做的是创建一个TestNg侦听器,它扩展了默认行为,并在所有测试完成后执行一些魔法操作。

public class FixRetryListener extends TestListenerAdapter {

    @Override
    public void onFinish(ITestContext testContext) {
        super.onFinish(testContext);

        // List of test results which we will delete later
        List<ITestResult> testsToBeRemoved = new ArrayList<>();

        // collect all id's from passed test
        Set <Integer> passedTestIds = new HashSet<>();
        for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) {
            passedTestIds.add(TestUtil.getId(passedTest));
        }

        Set <Integer> failedTestIds = new HashSet<>();
        for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) {

            // id = class + method + dataprovider
            int failedTestId = TestUtil.getId(failedTest);

            // if we saw this test as a failed test before we mark as to be deleted
            // or delete this failed test if there is at least one passed version
            if (failedTestIds.contains(failedTestId) || passedTestIds.contains(failedTestId)) {
                testsToBeRemoved.add(failedTest);
            } else {
                failedTestIds.add(failedTestId);
            }
        }

        // finally delete all tests that are marked
        for (Iterator<ITestResult> iterator = testContext.getFailedTests().getAllResults().iterator(); iterator.hasNext(); ) {
            ITestResult testResult = iterator.next();
            if (testsToBeRemoved.contains(testResult)) {
                iterator.remove();
            }
        }

    }

}
    null
public class TestUtil {

    public static int getId(ITestResult result) {
        int id = result.getTestClass().getName().hashCode();
        id = 31 * id + result.getMethod().getMethodName().hashCode();
        id = 31 * id + (result.getParameters() != null ? Arrays.hashCode(result.getParameters()) : 0);
        return id;
    }
}
@DataProvider(name = "dataprovider")
public Object[][] getData() {
    return new Object[][]{{System.currentTimeMillis()}};
}

对于失败的测试,将重新计算dataprovider。因此,您将获得一个新的时间戳,并且对于同一mehod的result1和result2将导致不同的哈希值。解决方案是在getId()方法中包含parameterIndex而不是parameters,但ItestResult中似乎没有包含这样的值。

请参阅以下简单示例作为概念证明:

@Listeners(value = FixRetryListener.class)
public class SimpleTest {

    private int count = 0;

    @DataProvider(name = "dataprovider")
    public Object[][] getData() {
        return new Object[][]{{"Run1"},{"Run2"}};
    }

    @Test(retryAnalyzer = RetryAnalyzer.class, dataProvider = "dataprovider")
    public void teste(String testName) {
        count++;
        System.out.println("---------------------------------------");
        System.out.println(testName + " " + count);
        if (count % 3 != 0) {
            Assert.fail();
        }

        count = 0;
    }

}

将屈服于:

Total tests run: 2, Failures: 0, Skips: 0
 类似资料:
  • 然后尝试重新运行: -mvn test-dsurefire.suitexmlfiles=target/surefire-reports/testng-faild.xml 在这个例子中,我有3个测试,在第二个运行中,我得到以下信息: null 最大的问题是它真的在执行所有的三个测试,而我只想重新执行失败的一个。

  • 问题内容: 如果测试失败,我想截图。与其将所有测试方法都包裹在try / catch块中,不如将这种逻辑添加到以标记的方法中。 如何在当前测试失败的注解方法中进行检测? 问题答案: 如果带有注释的方法具有参数,则TestNG将自动注入测试结果。(来源:TestNG文档,第5.18.1节) 这应该做的工作:

  • 而且,如果从Eclipse运行这样的测试,即使测试被移除,当套件完成时,失败仍然会打印在日志中。 关于RetryAnalyzer:我根本不考虑使用RetryAnalyzer的良好/最佳实践,但如果您发现自己处于需要解决问题的情况下,例如,您继承了一个依赖RetryAnalyzer的测试套件,您可能会发现这很有用。

  • 我们用Rest Assured和JUnit 5编写了API测试,并试图并行运行测试,因为测试之间没有依赖关系。我们已经尝试了JUnit 5的实验性并行执行,方法是设置: …但我们已经看到,通常当测试失败时,测试报告中不包含它们的输出。 这是已知问题吗?有什么变通方法吗?

  • “通过”测试但配置失败的示例。 配置失败:@afterclass tearDown java.lang.assertionerror:java.lang.assertionerror:应为[true],但在org.testng.assert.fail(assert.java:96)在links.testarea.tearDown(Testarea.java:96)在sun.reflect.nati