`
shijunjuan
  • 浏览: 46857 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

如何解决TestNG Retry的问题

阅读更多
我们使用TestNG来作为自动化测试框架的基础。在运行一批test case之后呢,我们希望能够自动Retry failed的test case。TestNG提供了一个IRetryAnalyzer 的接口,在@Test annotation里面可以指定使用Retry类来执行retry的功能。
@Test(retryAnalyzer = TestRetryAnalyzer.class)

TestRetryAnalyzer类实现了IRetryAnalyzer接口。
实现逻辑为:在retry方法里,判断Retry次数是否已经超过指定的最大retry次数。如果没有返回true,否则返回false。
_______________________________________________________________________________
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;

public class TestRetryAnalyzer implements IRetryAnalyzer {
private static final String TEST_RETRY_COUNT = "testRetryCount";
private int count = 1;
private int maxCount = 1;

public TestRetryAnalyzer() {
String retryMaxCount = System.getProperty(TEST_RETRY_COUNT);
if (retryMaxCount != null) {
maxCount = Integer.parseInt(retryMaxCount);
}
}

public int getCount() {
return this.count;
}

public int getMaxCount() {
return this.maxCount;
}

public synchronized boolean retry(ITestResult result) {
String testClassName = String.format("%s.%s", result.getMethod()
.getRealClass().toString(), result.getMethod().getMethodName());

if (count <= maxCount) {
result.setAttribute("RETRY", new Integer(count));

Logging.log("[RETRYING] " + testClassName + " FAILED, "
+ "Retrying " + count + " time", true);

count += 1;
return true;
}
return false;
}
}
_______________________________________________________________________________

然后,我们需要定义一个TestNGListener,来处理TestCase Retry的状态。在onTestFailure方法里,未达到最大retry次数的失败Case,我们把它的状态设置为SKIP,这样TestNG不会把它统计为Failed的test case。

在OnFinish方法里面处理最后TestCase的Result。

public class RetryTestListener extends TestListenerAdapter  {

public synchronized void onTestFailure(ITestResult arg0) {
if (arg0.getMethod().getRetryAnalyzer() != null) {
TestRetryAnalyzer testRetryAnalyzer = (TestRetryAnalyzer) arg0.getMethod().getRetryAnalyzer();

if (testRetryAnalyzer.getCount() <= testRetryAnalyzer.getMaxCount()) {
arg0.setStatus(ITestResult.SKIP);
Reporter.setCurrentTestResult(null);
}
else
failedCases.addResult(arg0, arg0.getMethod());

isRetryHandleNeeded = true;
}
}

public void onFinish(final ITestContext arg0) {
if(isRetryHandleNeeded)
{
removeIncorrectlySkippedTests(arg0,failedCases);
removeFailedTestsInTestNG(arg0);
}else
{
skippedCases = arg0.getSkippedTests();
failedCases = arg0.getFailedTests();
}

}

TestNG可能会把TestCase同时放在Skipped和Failed里面,所以我们在Skipped的testcase里面剔除真正Failed的Test Case(最后一次Retry失败的Case)

protected IResultMap removeIncorrectlySkippedTests(ITestContext test,IResultMap map)
{   
  List<ITestNGMethod> failsToRemove = new ArrayList<ITestNGMethod>();
  IResultMap returnValue = test.getSkippedTests();

  for(ITestResult result : returnValue.getAllResults())
  {
    for(ITestResult resultToCheck : map.getAllResults())
    {
        if(resultToCheck.getMethod().equals(result.getMethod()))
        {
            failsToRemove.add(resultToCheck.getMethod());
            break;
        }
    }  
    for(ITestResult resultToCheck : test.getPassedTests().getAllResults())
    {
        if(resultToCheck.getMethod().equals(result.getMethod()))
        {
            failsToRemove.add(resultToCheck.getMethod());
            break;
        }
    }   
  }

  for(ITestNGMethod method : failsToRemove)
  {
      returnValue.removeResult(method);
  }
  skippedCases = returnValue;


  return returnValue;
}

IResultMap只提供了删除某个方法的removeResult(Method)方法,如果使用了Dataprovider,我们不能直接调用此方法在FailedResult里面直接删除该方法的结果。这会造成test case结果的混淆。同一个TestMethod可能一个Data的结果Pass,另一个Data的结果Failed。所以我们使用failedCases来记录真正失败的result。同时我们在自己的Report中把FailedCases显示出来。
在下面这个方法里面,我们在failedTests里面查找,如果failedCases里面没有该方法,就把该方法的结果删除掉。这样确保TestNG能够报告Suite的整体Pass/Fail状态。有些同学问,为什么要这么做?我们之前不是把testcase设置为skip了么?还记得我们前面提过的,TestNG可能会把result放在两个Map里面了,所以还是需要做这一步来确保正确。

private void removeFailedTestsInTestNG(ITestContext test)
{   
  IResultMap returnValue = test.getFailedTests();


  for(ITestResult result : returnValue.getAllResults())
  {

    boolean isFailed = false;
  
    for(ITestResult resultToCheck : failedCases.getAllResults())
    {
        if(result.getMethod().equals(resultToCheck.getMethod()))
        {
        System.out.println("Passed:"+result.getMethod().getMethodName());
        isFailed = true;
            break;
        }
    }
    if(!isFailed)
    {
    returnValue.removeResult(result.getMethod());
    test.getFailedConfigurations().removeResult(result.getMethod());
    }
  }

}

}

我们这么做了之后,基本能够保证报告的正确性。但是TestNG的Retry对DataProvider的支持 不 够 好,详 情 参 考https://groups.google.com/forum/#!msg/testng-users/7S9BFshqivk/R0dCG14kSccJ 
另外,此代码基于TestNG 6.7 之上。

CI 中也需要做修改。否则Retry成功了,CI仍然会报告失败。

   
<plugin>                                      <groupId>org.apache.maven.plugins</groupId>                                      <artifactId>maven-surefire-plugin</artifactId>                                      <version>2.9</version>                                      <configuration>                                                <suiteXmlFiles>                                                         <suiteXmlFile>src/main/java/com/ebay/maui/test/demo/testng_retry.xml</suiteXmlFile>                                                </suiteXmlFiles>                                                <properties>                                                         <property>                                                           <name>usedefaultlisteners</name>                                                           <value>false</value>                                                         </property>                                                         <property>                                                           <name>listener</name>                                                           <value>com.ebay.maui.reporter.HTMLReporter</value>                                                         </property>                                                </properties>                                      </configuration>                            
</plugin>
分享到:
评论

相关推荐

    testng-retry-example

    TestNG 重试示例这是一个示例,展示如何使用 TestNG 编写测试,当测试失败时将重试。 当测试代码的行为不是 100% 一致时,它很有用。 在注释中将 retryAnalyzer 与 MyRetryAnalyzer 分开的测试用例将在测试失败时...

    testng-xslt-1.1.2.zip

    3. **文档**:可能包含用户指南、API参考或示例,帮助开发者了解如何使用这个扩展,并解决可能出现的问题。 4. **库文件**:可能包含依赖的JAR文件,如TestNG本身和其他必要的库,确保扩展能正确运行。 在实际应用...

    testng-6.7.jar TestNG依赖包

    通过引入"testng-6.7.jar",开发者可以解决因缺少TestNG依赖而导致的编译或运行错误,进一步提升测试工作的效率和质量。同时,了解并熟练使用`CommandLineArgs`类可以帮助更好地控制和定制TestNG测试的执行。

    testng.zip离线安装

    TestNG是一款功能强大的Java测试框架,它扩展...通过离线安装TestNG,开发者可以避免因网络问题而无法使用这个强大的测试工具。离线安装不仅适用于个人开发,对于那些网络受限的企业环境,也是一项非常实用的解决方案。

    testng-6.9.4和testng-6.8.8.zip

    TestNG是Java编程语言中的一款强大的自动化测试框架,与JUnit和Selenium等工具配合使用,为软件测试提供了全面且灵活的解决方案。TestNG由Cédric Beust创建,旨在提高测试效率并支持更复杂的测试场景,如并发测试、...

    TestNG离线安装文件 site

    TestNG是一种广泛使用的Java测试框架,它为开发者和测试工程师提供了功能强大且灵活的测试解决方案。这个"TestNG离线安装文件site"包含了在没有网络连接的情况下为Eclipse集成TestNG环境所需的所有组件,特别适合...

    eclipse-testng离线包

    1. **TestNG基础**:TestNG由Cedric Beust创建,设计目标是提供比JUnit更全面的测试解决方案。它支持类、方法、配置方法、数据驱动测试、参数化测试、依赖性测试等多种测试模型。 2. **Eclipse TestNG插件**:该...

    testng测试报告模板BeautifulReport.7z

    总而言之,这个压缩包提供了一套完整的解决方案,帮助TestNG用户生成美观且定制化的测试报告,提升测试过程的专业性和效率。通过深入理解和运用这些资源,你可以更好地管理和优化你的测试框架,确保测试过程的透明度...

    TestNG-离线安装包

    TestNG-6.9离线安装包,下载zip解压后,直接拷贝到eclipse下的dropins目录下即可。重启eclipse,TestNG插件即安装成功。重启eclipse会自动安装TestNG插件,所以启动时间较长,请耐心等待。大概3-5min左右。

    TestNG安装包

    TestNG是一个Java的框架,所以第一个要求是JDK要安装在你的机器上。 系统要求 JDK 1.5或以上 内存 没有最低要求 磁盘空间 没有最低要求 操作系统 没有最低要求 步骤1 -验证Java安装在你的机器上 现在,打开...

    maven testng 报告中文乱码(csdn)————程序.pdf

    本文将深入探讨Maven TestNG报告中文乱码的问题,并提供解决方案。 Maven是一个流行的Java项目管理工具,它通过使用POM(Project Object Model)来管理项目的构建、报告和依赖。TestNG是一款功能强大的测试框架,...

    testng-6.10.jar

    6. **报告生成**:TestNG提供了内置的HTML测试报告,详细记录每个测试用例的结果,包括失败的堆栈跟踪,有助于调试和问题定位。 7. **异常处理**:TestNG允许声明预期的异常,如果测试方法抛出与预期匹配的异常,则...

    Testng JAR包及教程

    TestNG是一款强大的测试框架,专为Java开发人员设计,提供了丰富的功能来支持单元测试、集成测试以及端到端测试。它的出现是对JUnit的一种扩展,增加了许多高级特性,如并发测试、参数化测试、依赖管理以及更详细的...

    TestNG教程.pdf

    TestNG(Testing New Generation)是一个开源的自动化测试框架,用于简化单元测试、集成测试、端到端测试等不同层次的测试需求。它受JUnit和NUnit的启发,并且引入了一些新功能,使得测试过程更加强大和方便。 在...

    testng-xslt-1.1.2-master

    TestNG-XSLT是针对TestNG测试框架的一个扩展工具,主要功能是通过...通过理解和应用这些知识点,开发团队能够更好地管理和优化他们的测试流程,提高测试效率,并且能够更直观地理解测试报告,从而快速定位和解决问题。

    testng 6.14 离线包

    为了解决这个问题,我们可以选择下载TestNG的离线安装包进行手动安装。离线安装包通常包含了所有必要的组件和依赖,确保用户在没有网络连接的情况下也能顺利完成安装。 离线包中包含的文件列表如下: 1. `p2.index...

    testNG6.11.0

    1.下载testNG 离线安装包【eclipse-testng离线包】,并解压。 2.将解压后的文件..\eclipse-testng离线包\features\目录下的文件夹org.testng.eclipse_6.11.0.201703011520放到eclipse安装路径下的features目录下 3....

    TestNG-6.3 测试框架

    TestNG是一款功能强大的自动化测试框架,相较于JUnit,它提供了更多的特性和灵活性,使得测试工作更加高效和全面。在TestNG 6.3版本中,我们可以看到一些关键特性,这些特性对于提升测试质量和效率至关重要。 首先...

    myeclipse2017 TestNg6.15插件

    它是由Cédric Beust创建的,作为JUnit的增强版本,旨在提供更全面、更灵活的测试解决方案。TestNG 6.15是该框架的一个特定版本,带来了诸多改进和特性。 首先,TestNG的核心优势在于其支持多种测试类型,包括单元...

Global site tag (gtag.js) - Google Analytics