首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >testng中重试失败的测试用例

testng中重试失败的测试用例
EN

Stack Overflow用户
提问于 2015-01-29 14:22:44
回答 3查看 3.6K关注 0票数 2

我正在做一个testng项目,我的目标是让testng自动重试失败的测试用例。例如,第一轮有10个测试用例,其中5个失败。因此,在第一轮之后,我让testng选择5个失败的测试用例,并再次运行它们。在第二轮中,可能有2个失败的测试用例,然后我重新运行这个2年。

我试过IRetryAnalyzer,但它不同。IRetryAnalyzer会立即重试失败的测试用例,而不是在每轮结束时重试。

因此,目前我想在ISuiteListener中使用onStart和onFinish调用重试。在本例中,我像这样实现了onFinish方法:

代码语言:javascript
复制
@Override
public void onFinish(ISuite suite) {
    logger.info("Round " + retryCounter
            + " Testing suit stops. onFinish method is invoked.");
    if (!doRetry()) {
        logger.info("Retry finished.");
        cleanReport(suite);
        return;
    }

    // I want to remove the passed cases here
    // and create a suite to run the failed test cases.
    suite.run();
}

那么,有可能做到这一点吗?或者有什么更好的想法来满足这个需求。

EN

回答 3

Stack Overflow用户

发布于 2016-03-31 06:22:58

这个问题看起来很老了,但仍然没有答案,所以这是我的解决方案。

首先,您必须像这样实现IRetryAnalyzer接口:

代码语言:javascript
复制
    public class Retry implements IRetryAnalyzer {

    private int retryCount = 0;
    private int maxRetryCount = 1;

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

这里,maxRetryCount是您希望重新运行失败测试的次数。测试失败后立即重新运行。

其次,实现IAnnotationTransformer接口:

代码语言:javascript
复制
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);
        }

    }
}

现在,在带有测试的TestNG xml套件中,您应该添加侦听器:

代码语言:javascript
复制
<listeners>
    <listener class-name="Utils.reRunTest.RetryListener"/>
</listeners>

您还可以将其添加到pom.xml文件中:

代码语言:javascript
复制
 <properties>
     <property>
         <name>usedefaultlisteners</name>
         <value>false</value>
     </property>
     <property>
         <name>listener</name>
         <value>org.testng.reporters.EmailableReporter2, org.testng.reporters.XMLReporter, org.testng.reporters.FailedReporter, Utils.reRunTest.RetryListener
         </value>
     </property>

您可能还希望测试重新运行不会影响测试的总数。这是通过实现TestListener接口并将其作为侦听器与RetryAnalyzer一起添加来实现的。将从测试总数中删除薄片测试和失败测试的实现是:

代码语言:javascript
复制
public class TestListener implements ITestListener {
    @Override
    public void onFinish(ITestContext context) {
        Set<ITestResult> failedTests = context.getFailedTests().getAllResults();
        Set<ITestResult> skippedTests = context.getSkippedTests().getAllResults();
        for (ITestResult temp : failedTests) {
            ITestNGMethod method = temp.getMethod();
            if (context.getFailedTests().getResults(method).size() > 1) {
                failedTests.remove(temp);
            } else {
                if (context.getPassedTests().getResults(method).size() > 0) {
                    failedTests.remove(temp);
                }
            }
        }
        for (ITestResult temp : skippedTests) {
            ITestNGMethod method = temp.getMethod();
            if (context.getSkippedTests().getResults(method).size() > 1) {
                skippedTests.remove(temp);
            } else {
                if (context.getPassedTests().getResults(method).size() > 0) {
                    skippedTests.remove(temp);
                }
            }
        }
    }

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

希望这能有所帮助。附注:不要在TestNG版本6.9.10中使用它,因为它有一些问题,你重新运行测试总是会通过的,而不考虑它们的真实状态。

票数 2
EN

Stack Overflow用户

发布于 2015-01-29 19:24:30

Testng在运行后在输出文件夹中创建一个testng-failed.xml,您可以在运行testng.xml之后运行该文件。因此,您在testng.xml中有10个测试用例并运行它们,任何失败的测试用例都会出现在testng-failed.xml中,然后您就可以运行它了。

票数 0
EN

Stack Overflow用户

发布于 2022-02-02 03:04:18

如果testng版本是7.4.0或更高版本,那么重试测试用例将获得总计数,并且还会出现跳过部分。

为了解决这个问题,我们需要在TestListener类中做一点代码更改。

下面的代码片段适用于我。

代码语言:javascript
复制
public class RetryAnalyzer extends RetryAnalyzerCount
{

    @Override
    public boolean retryMethod(ITestResult result)
    {
        int count = 0;
        int trackingCount = 0;
        Properties prop = new Properties();
        String dir = null;
        FileInputStream input = null;
        
        try
        {
            //Reading Property file to get Retry Count.
            dir = new File(System.getProperty("user.dir")).getParent();
            dir = dir + "Your Properties Path";
            input = new FileInputStream(dir);
            prop.load(input);
        }
        catch (FileNotFoundException e)
        {
            count = 1;
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        count = Integer.parseInt(prop.getProperty("RetryCount"));
        
        if (!result.isSuccess())
        {
            while (count != 0)
            {
                count--;
                trackingCount++;
                result.setStatus(ITestResult.SUCCESS_PERCENTAGE_FAILURE);
                String message = Thread.currentThread().getName() + "Error in '" + result.getName() + "' with status '" + result.getStatus() + "'. Retrying '" + trackingCount + "' times.";
                Reporter.log(message, true);
                return true;
            }
        }
        return false;
        
    }
}

在这里,我们在一个属性文件中维护三次重试计数,这样我们就可以在不编译代码的情况下更改重试计数。

下面是属性文件的值。

代码语言:javascript
复制
RetryCount=1

在此之后,我们需要更改TestListener类。

代码语言:javascript
复制
    @Override
    public void onFinish(ITestContext context)
    {
        //extent.flush();
        Set<ITestResult> failedTests = context.getFailedTests().getAllResults();
        Set<ITestResult> skippedTests = context.getSkippedTests().getAllResults();
        Set<ITestResult> passedTests = context.getPassedTests().getAllResults();
        for (ITestResult temp : failedTests) {
            ITestNGMethod method = temp.getMethod();
            System.out.println("Method Name  " + method.getMethodName() + "  Have Result " + temp.getStatus() + "  Have Retries ?  " +temp.wasRetried() + " \n " + " have result " +context.getFailedTests().getResults(method).toString());
            if (temp.wasRetried()){
                failedTests.remove(temp);
            }
        }
        for (ITestResult temp : skippedTests) {
            ITestNGMethod method = temp.getMethod();
            System.out.println("Method Name  " + method.getMethodName() + "  Have Result " + temp.getStatus() + "   Have Retries ?  " +temp.wasRetried() + " \n " + " Have Result " + context.getSkippedTests().getResults(method).toString());
            if (temp.wasRetried()){
                skippedTests.remove(temp);
            }
        }
        for (ITestResult temp : passedTests) {
            ITestNGMethod method = temp.getMethod();
            System.out.println("Method Name  " + method.getMethodName() + "  Have Result " + temp.getStatus() + "   Have Retries ?  " +temp.wasRetried() + " \n " + " Have Result " + context.getPassedTests().getResults(method).toString());
            if (temp.wasRetried()){
                passedTests.remove(temp);
            }
        }
   }

它将从skip部分中删除重试测试用例计数。

现在,如果您在测试用例级别重试测试用例,只需添加

代码语言:javascript
复制
@Test(retryAnalyzer=RetryAnalyzer.class,timeOut = DEFAULT_TEST_TIMEOUT, description = "XXX", dataProvider = "YYY", groups ={"ZZZ"})
    public void test_A() {

    }

但是,如果您在套件级别重试测试用例,则需要创建另一个类

代码语言:javascript
复制
public class AnnotationTransformer implements IAnnotationTransformer {

    @Override
    public void transform(ITestAnnotation annotation, Class testClass,Constructor testConstructor ,Method testMethod)
    {
        annotation.setRetryAnalyzer(RetryAnalyzer.class);
    }
}

然后在testng.xml文件中调用它。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="RetryFailedTests" verbose="1" preserve-order="true" parallel="methods" thread-count="1" >
  <listeners>
        <listener class-name="AnnotationTransformer"/>
  </listeners>
  <test name="RetryMulitple">
        <classes> 
            <class name="Your TestCase"></class>   
        </classes>
    </test>
 </suite>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28208202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档