• testng执行用例失败,再次执行


    我们通过重写testng的retry方法和transform方法来实现用例失败重跑的功能。

    首先添加两个文件

    TestngRetry.java

    public class TestngRetry implements IRetryAnalyzer {
        private static Logger logger = Logger.getLogger(TestngRetry.class);
        private static int maxRetryCount = 3;
        private int retryCount = 1;
    
        @Override
        public boolean retry(ITestResult result) {
            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;
            }
            return false;
        }
    }

    RetryListener.java

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

    添加以上两个文件之后,有两种方法可以使用我们的listener进行监听:

    在Test标签中添加retryAnalyzer属性

    @Test(retryAnalyzer = com.xxx.retry.RetryListener.class)
    • 在testng.xml文件中配置listener
    <test name="test1">
        <listeners>
            <listener class-name="com.xxx.retry.RetryListener" />
        <classes>
            <class name="com.xxx.test.NewTest" />
        </classes>
    </test>

    做完上面的工作,我们就可以实现失败重跑的功能了。但是,每次用例重跑之后,每次失败的结果也记录在运行结果中了,测试结果中运行的用例数增加了,不利于我们查看测试结果。因此,我们还需要把重复的用例去掉。 
    这个我们通过重写TestListenerAdapter中的onFinish方法实现:

    TestngListener.java

    public class TestngListener extends TestListenerAdapter {
        private static Logger logger = Logger.getLogger(TestngListener.class);
        @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());
                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;
        }
    }

    把listener添加到testng.xml中,当前testng.xml为:

    <test name="test1">
        <listeners>
            <listener class-name="com.xxx.retry.RetryListener" />
            <listener class-name="com.xxx.retry.TestngListener" />
        </listeners>
        <classes>
            <class name="com.xxx.test.NewTest" />
        </classes>
    </test>

    OK,结束。

  • 相关阅读:
    spring @component的作用
    Spring 开启Annotation <context:annotation-config> 和 <context:component-scan>诠释及区别
    servlet中实现页面跳转return “r:”和return “f:
    MyEclipse中SVN的使用方法 此博文包含图片 (2012-04-19 12:18:35)
    MyEclipse使用总结——MyEclipse10安装SVN插件
    javaweb学习总结(九)—— 通过Servlet生成验证码图片
    Spring-springmvc-mybatis整合
    MyBatis连接SQLServer数据库
    mybatis入门基础(二)----原始dao的开发和mapper代理开发
    MyBatis入门基础(一)
  • 原文地址:https://www.cnblogs.com/longronglang/p/7457960.html
Copyright © 2020-2023  润新知