gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 22:34:57 39 4
gpt4 key购买 nike

设置:
我有一个扩展 IRetryAnalyzer 的类,并实现了一个简单的重试逻辑,覆盖了以下方法:
公共(public) bool 重试(ITestResult 结果){

我有另一个扩展类 TestListenerAdapter 的类,它重试失败的测试,直到它们通过或报告失败。我已经实现了覆盖以下方法的逻辑:
公共(public)无效 onTestFailure(ITestResult 结果){

场景:
我总共有 10 个测试。 10 次测试中有 1 次失败 2 次,并使用我的重试逻辑在第 3 次尝试中通过。测试结果显示如下:
总测试:12,失败:2,跳过:0

我想要的是输出正确数量的测试运行。并且也忽略了自测试结束以来的 2 次失败。所以结果应该是这样的:
总测试:10,失败:0,跳过:0

我在这里想念什么?我需要修改 ITestResult 对象吗?如果是,如何?

仅供引用:我能够使用 JUnit(实现 TestRule 接口(interface))来实现这一点。

提前致谢。

最佳答案

请考虑以下最大测试结果。 2 次重试:

  • 通过 => 总体还行!
  • 失败,通过 => 总体还行!
  • 失败,失败,通过 => 总体还行!
  • 失败,失败,失败 => 整体失败!

  • 我所做的是创建一个 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();
    }
    }

    }

    }

    基本上我做两件事:
  • 收集所有通过的测试。如果我遇到至少一个通过测试的失败测试,​​我会删除失败的测试(这将涵盖上面的案例 2 和 3)
  • 遍历所有失败的测试。如果我遇到以前失败的失败测试,​​我会删除当前失败的结果。 (这实际上涵盖了案例 3​​ 和 4)。这也意味着如果有几个失败的结果,我只会保留第一个失败的结果。

  • 为了识别测试结果,我使用以下简单的哈希函数:
    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()}};
    }

    对于失败的测试,将重新评估数据提供者。因此,您将获得一个新的时间戳,并且相同方法的 result1 和 result2 将产生不同的哈希值。解决方案是在 getId() 方法中包含 parameterIndex 而不是参数,但似乎 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

    关于TestNG 重试失败的测试不会输出正确的测试结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13131912/

    39 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com