如何解决TestNG Retry的问题

更新时间:2023-09-30 23:11:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

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

TestRetryAnalyzer类实现了IRetryAnalyzer接口。

实现逻辑为:在retry方法里,判断Retry次数是否已经超过指定的最大retry次数。如果没有返回true,否则返回false。

_______________________________________________________________________________ importorg.testng.IRetryAnalyzer; importorg.testng.ITestResult;

public class TestRetryAnalyzer implements IRetryAnalyzer { private static final String TEST_RETRY_COUNT = \ privateint count = 1; privateintmaxCount = 1; publicTestRetryAnalyzer() { String retryMaxCount = System.getProperty(TEST_RETRY_COUNT); if (retryMaxCount != null) { maxCount = Integer.parseInt(retryMaxCount); } } publicintgetCount() { returnthis.count; } publicintgetMaxCount() { returnthis.maxCount; } public synchronized boolean retry(ITestResult result) { String testClassName = String.format(\ .getRealClass().toString(), result.getMethod().getMethodName()); if (count <= maxCount) { result.setAttribute(\ Logging.log(\ + \ 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 {

publicsynchronizedvoidonTestFailure(ITestResult arg0) {

public void onFinish(final ITestContext arg0) {

if(isRetryHandleNeeded)

}

{ { }

skippedCases = arg0.getSkippedTests(); failedCases = arg0.getFailedTests();

removeIncorrectlySkippedTests(arg0,failedCases); removeFailedTestsInTestNG(arg0);

}

}

isRetryHandleNeeded = true;

if (arg0.getMethod().getRetryAnalyzer() != null) {

TestRetryAnalyzertestRetryAnalyzer = (TestRetryAnalyzer)

if (testRetryAnalyzer.getCount() <= } else

failedCases.addResult(arg0, arg0.getMethod()); arg0.setStatus(ITestResult.SKIP); Reporter.setCurrentTestResult(null);

arg0.getMethod().getRetryAnalyzer();

testRetryAnalyzer.getMaxCount()) {

}else

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

protectedIResultMapremoveIncorrectlySkippedTests(ITestContexttest,IResultMap map)

IResultMap只提供了删除某个方法的removeResult(Method)方法,如果使用了

Dataprovider,我们不能直接调用此方法在FailedResult里面直接删除该方法的结果。这会造成test case结果的混淆。同一个TestMethod可能一个Data的结果Pass,另一个Data的结果Failed。所以我们使用failedCases来记录真正失败的result。同时我们在for(ITestResult result : returnValue.getAllResults()) {

for(ITestResultresultToCheck : map.getAllResults()) {

if(resultToCheck.getMethod().equals(result.getMethod())) {

failsToRemove.add(resultToCheck.getMethod()); break; } }

for(ITestResultresultToCheck : {

if(resultToCheck.getMethod().equals(result.getMethod())) {

failsToRemove.add(resultToCheck.getMethod()); break; } } }

for(ITestNGMethod method : failsToRemove) {

returnValue.removeResult(method); }

skippedCases = returnValue;

returnreturnValue; } {

ListfailsToRemove = newArrayList(); IResultMapreturnValue = test.getSkippedTests();

test.getPassedTests().getAllResults())

自己的Report中把FailedCases显示出来。

在下面这个方法里面,我们在failedTests里面查找,如果failedCases里面没有该方法,就把该方法的结果删除掉。这样确保TestNG能够报告Suite的整体Pass/Fail状态。有些同学问,为什么要这么做?我们之前不是把testcase设置为skip了么?还记得我们前面提过的,TestNG可能会把result放在两个Map里面了,所以还是需要做这一步来确保正确。

privatevoidremoveFailedTestsInTestNG(ITestContext test) … }

test.getFailedConfigurations().removeResult(result.getMethod()); } } }

System.out.println(\+result.getMethod().getMethodName());

isFailed = true; break; } }

if(!isFailed) {

returnValue.removeResult(result.getMethod()); {

IResultMapreturnValue = test.getFailedTests();

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

for(ITestResultresultToCheck : failedCases.getAllResults()) {

if(result.getMethod().equals(resultToCheck.getMethod())) {

booleanisFailed = false;

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

另外,此代码基于TestNG 6.7 之上。

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

org.apache.maven.plugins maven-surefire-plugin 2.9

src/main/java/com/ebay/maui/test/demo/testng_retry.xml

usedefaultlisteners false

listener

com.ebay.maui.reporter.HTMLReporter

本文来源:https://www.bwwdw.com/article/9i2d.html

Top