美文网首页
3、testng失败重试

3、testng失败重试

作者: ltjxwxz | 来源:发表于2017-10-17 14:35 被阅读0次

需求:一个用例执行失败后再执行几次,避免因为环境不稳定等外部因素引发的失败
代码如下:

  • RetryListener
//修改@Test(retry)注解
public class RetryListener implements IAnnotationTransformer {
    @Override
    public void transform(ITestAnnotation annotation, Class testClass, 
            Constructor testConstructor, Method testMethod) {
        IRetryAnalyzer retry = annotation.getRetryAnalyzer();
        if (retry == null) {
            annotation.setRetryAnalyzer(TestngRetry.class);
        }       
    }
}
  • TestngListener
// 用例级别的监控
public class TestngListener extends TestListenerAdapter {
    private static Logger logger = LoggerFactory.getLogger(TestngListener.class);

    @Override
    public void onTestFailure(ITestResult tr) {
        super.onTestFailure(tr);
        logger.info(tr.getName() + " Failure");
    }

    @Override
    public void onTestSkipped(ITestResult tr) {
        super.onTestSkipped(tr);
        logger.info(tr.getName() + " Skipped");
    }

    @Override
    public void onTestSuccess(ITestResult tr) {
        super.onTestSuccess(tr);
        logger.info(tr.getName() + " Success");
    }

    // 统计当前已经执行了多少个用例 及状态
    @Override
    public void onTestStart(ITestResult tr) {
        super.onTestStart(tr);
        logger.info(tr.getName() + " Start");
        ITestContext context = tr.getTestContext();
        int passedCount = context.getPassedTests().size();
        int faileCount = context.getFailedTests().size();
        int skipCount = context.getSkippedTests().size();
        int totalCount = passedCount + faileCount + skipCount;
        System.out.println("成功个数:" + passedCount);
        System.out.println("失败个数:" + faileCount);
        System.out.println("跳过个数:" + skipCount);
        System.out.println("当前执行总个数:" + totalCount);
    }

    // 减去失败重试的次数,即使有失败重试,总用例数保持不变
    @Override
    public void onFinish(ITestContext testContext) {
        super.onFinish(testContext);

        // List of test results which we will delete later
        ArrayList<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>();
        // collect all id's from passed test
        Set<Integer> passedTestIds = new HashSet<Integer>();
        for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) {
            logger.info("PassedTests = " + passedTest.getName());
            passedTestIds.add(getId(passedTest));
        }

        Set<Integer> failedTestIds = new HashSet<Integer>();
        for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) {
            logger.info("failedTest = " + failedTest.getName());
            // id = class + method + dataprovider
            int failedTestId = 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)) {
                logger.info("Remove repeat Fail Test: " + testResult.getName());
                iterator.remove();
            }
        }
    }

    private int getId(ITestResult result) {
        int id = result.getTestClass().getName().hashCode();
        id = id + result.getMethod().getMethodName().hashCode();
        id = id + (result.getParameters() != null ? Arrays.hashCode(result.getParameters()) : 0);
        return id;
    }
}
  • TestngRetry
public class TestngRetry implements IRetryAnalyzer {
    private static Logger logger = LoggerFactory.getLogger(TestngRetry.class);
    private int retryCount = 1;
    private static int maxRetryCount;
    static {
        //外围文件配置最大运行次数
        maxRetryCount = 2;
        logger.info("maxRunCount=" + (maxRetryCount));
    }

    /* 
     * return true表示没达到最大运行次数,如果执行失败,还会继续重试
     * return false表示达到最大运行次数
     */
    @Override
    public boolean retry(ITestResult result) {
        System.out.println("执行结果:" + result.isSuccess());
        if (retryCount <= maxRetryCount) {
            String message = "running retry for  '" + result.getName() + "' on class " + 
                                       this.getClass().getName() + " Retrying " + retryCount + " times";
            logger.info(message);
            Reporter.setCurrentTestResult(result);
            Reporter.log("RunCount=" + (retryCount + 1));
            retryCount++;
            return true;
        }
        /*
         * 同一个测试方法,如果第一条数据重试过了retryCount达到最大,第二条数据就不会再重试,
         * 需要把retryCount重新置为1
         */
        retryCount=1;
        return false;
    }
}
  • testng.xml
<listeners>
    <listener class-name="com.picc.autoTestingWeb.utils.testngUtils.RetryListener" />
</listeners>

注意:使用时加在testng.xml上,不能作为注解加在测试类上
testng官方文档有说明,IAnnotationTransformer只能加在配置文件上

相关文章

网友评论

      本文标题:3、testng失败重试

      本文链接:https://www.haomeiwen.com/subject/rytvyxtx.html