zoukankan      html  css  js  c++  java
  • testng跑失败用例重试

    testng 提高用例通过率,失败用例要重新运行一次

    步骤:

    1、新建一个Retry 类,implements IRetryAnalyzer接口,这个类里面确定重跑次数,以及分析每次失败是否需要重新运行

    import org.testng.IRetryAnalyzer;
    import org.testng.ITestResult;
    
    public class Retry implements IRetryAnalyzer {
        private int retryCount = 0;
        private int maxRetryCount = 1;
    
        @Override
        public boolean retry(ITestResult result) {
            if (retryCount < maxRetryCount) {
                System.out.println("Retrying test " + result.getName() + " with status "
                        + getResultStatusName(result.getStatus()) + " for the " + (retryCount + 1) + " time(s).");
                retryCount++;
    
                return true;
            }
            resetRetrycount(); // 每次跑完一条用例后,重置retryCount为0,这样dataProvider 数据驱动测试叶支持
            return false;
        }
    
        public String getResultStatusName(int status) {
            String resultName = null;
            if (status == 1)
                resultName = "SUCCESS";
            if (status == 2)
                resultName = "FAILURE";
            if (status == 3)
                resultName = "SKIP";
            return resultName;
        }
    
        public boolean isRetryAvailable() {
            return retryCount < maxRetryCount;
        }
    
        public void resetRetrycount() {
            retryCount = 0;
        }
    
    }

    2、新建一个RetryListener类,implements IAnnotationTransformer 主要功能是监听事件

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    import org.testng.IAnnotationTransformer;
    import org.testng.IRetryAnalyzer;
    import org.testng.annotations.ITestAnnotation;
    
    public class RetryListener implements IAnnotationTransformer {
    
        @Override
        public void transform(ITestAnnotation testannotation, Class testClass,
                Constructor testConstructor, Method testMethod)    {
            IRetryAnalyzer retry = testannotation.getRetryAnalyzer();
    
            if (retry == null)    {
                testannotation.setRetryAnalyzer(Retry.class);
            }
    
        }
    }

    3、测试结果处理,testng运行结果中,去掉重复运行的用例,即不论这个用例跑多少遍,都算一个用例

    import java.util.Set;
    
    import org.apache.log4j.Logger;
    import org.testng.ITestContext;
    import org.testng.ITestListener;
    import org.testng.ITestNGMethod;
    import org.testng.ITestResult;
    
    public class TestListener implements ITestListener {
        private static org.apache.log4j.Logger logger = Logger.getLogger(ITestListener.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());
                // 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;
        }*/
    
        public void onTestStart(ITestResult result) {
        }
    
        public void onTestSuccess(ITestResult result) {
        }
    
        public void onTestFailure(ITestResult result) {
        }
    
        public void onTestSkipped(ITestResult result) {
        }
    
        public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
        }
    
        public void onStart(ITestContext context) {
        }
    }  

    4、testng xml中配置监听

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Default suite">
    <listeners>
            <listener class-name="com.auto.listen1.RetryListener"/>
             <listener class-name="com.auto.listen1.TestListener"/>
      </listeners>
      <test verbose="2" name="Default test">
        <classes>
          <class name="com.auto.listen1.NewTest"/>
        </classes>
      </test> <!-- Default test -->
    </suite> <!-- Default suite -->

    5、新建一个测试类

    package com.auto.listen1;
    
    import org.testng.annotations.Test;
    import org.testng.Assert;
    import org.testng.annotations.DataProvider;
    import org.testng.annotations.Listeners;
    
    //@Listeners(value = MyTestListenerAdapter.class)
    public class NewTest {
        @Test(dataProvider = "dp")
        // @Test(retryAnalyzer = MyRetryAnalyzer.class,dataProvider = "dp")
        public void f(Integer n, String s) {
            System.out.println("ssssss:" + s);
            Assert.assertFalse(true);
        }
    
        }
        @DataProvider
        public Object[][] dp() {
            return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" },new Object[] { 3, "c" },new Object[] { 4, "d" } };
        }
    }

    运行结果:

    ssssss:a
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:a
    ssssss:b
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:b
    ssssss:b
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:b
    ssssss:c
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:c
    ssssss:c
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:c
    ssssss:c
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:c
    ssssss:d
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:d
    ssssss:d
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:d
    ssssss:d
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:d
    ssssss:d
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:d

    这个结果中,第一个参数a运行2遍,第二个参数b运行2*2=4遍,第三个参数c运行3*2=6遍,第四个参数d运行4*2=8遍,参数越多运行多余运行次数越多,这个是使用testng 6.9.10 版本问题,更新版本为6.9.13.6 后,运行结果正常如下:

    ssssss:a
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:a
    ssssss:b
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:b
    ssssss:c
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:c
    ssssss:d
    Retrying test f with status FAILURE for the 1 time(s).
    ssssss:d

    每个失败用例都重试一次

    版本问题参考:https://github.com/cbeust/testng/pull/740

    https://github.com/cbeust/testng/pull/1104

  • 相关阅读:
    绝对均匀图生成算法
    告别S! S! H! 秒杀终端工具——FastLogin快捷登录
    使用Atom打造无懈可击的Markdown编辑器
    程序异常分析指南
    javascript opacity兼容性随笔
    javascript event兼容性随笔
    javascript Xml兼容性随笔
    addEventListener、attachEvent、cancelBubble兼容性随笔
    算法--逆波兰表达式(数学逆波兰表达式和交并集逆波兰表达式)
    算法--区间数据计算
  • 原文地址:https://www.cnblogs.com/testway/p/6118148.html
Copyright © 2011-2022 走看看