自动化测试过过程中,有些testcase会因为各种原因失败,比如网络问题/服务器问题/数据库问题/系统问题/浏览器问题等等,作为自动化测试者,我们需要再次执行失败的测试用例,对于testng框架使用者,这里有两种方案来执行失败的用例。
方案一. 使用“testng-failed.xml”来执行失败的测试用例.
steps: 1. 在第一次执行完自动化测试之后,刷新项目文件夹。
2. 一个文件夹名为“test-output”自动生成,在该文件夹内,有一个文件是“testng-failed.xm”。
3. Run testng-failed.xml,就会再次执行失败的测试用例。
方案二. 通过实现TestNG IRetryAnalyzer接口来执行失败的测试用例
新建一个类来实现IRetryAnalyzer,并重写这个接口里面为一个的一个方法 retry
public class RetryAnalyzer implements IRetryAnalyzer { private int retryCount = 0; private static int retryLimit = 3; @Override public boolean retry(ITestResult result) { String testClassName = String.format("%s.%s", result.getMethod().getRealClass().toString(), result.getMethod().getMethodName()); if(retryCount < retryLimit){ Log.info("[RETRYING] " + testClassName + " FAILED, " + "Retrying " + (retryCount+1)+ " time", true); retryCount ++; CurrentManager.putParameter("retryCount", String.valueOf(retryCount)); return true; } else { return false; } } }
重写完这个retryAnalyzer接口之后,可以在test method上面加上这个类:
@Test(retryAnalyzer = RetryAnalyzer.class) public void test(){ Assert.assertEquals(1,2); }
然后再执行这个测试的时候,如果测试失败,就会自动retry 3次,重新执行这个测试用例。
除了上面这种方法,还可以用一个retryListener,在测试执行期间,就能对所有失败的测试用例re-run。
public class RetryListener implements IAnnotationTransformer { @Override public void transform(ITestAnnotation iTestAnnotation, Class aClass, Constructor constructor, Method method) { IRetryAnalyzer retryAnalyzer = iTestAnnotation.getRetryAnalyzer(); if(retryAnalyzer == null){ iTestAnnotation.setRetryAnalyzer(RetryAnalyzer.class); } } }
这里面用到了接口IAnnotationTransformer,他的方法transformer会在测试运行期间被每一个test method调用,这个接口会给每一个test method添加annotation。然后在testng.xml file中,添加这个listener:
<listeners> <listener class-name="com.stubhub.aroma.platform.controller.RetryListener" /> </listeners>
执行这个xml file,针对test suite里面所有的测试,失败的test method就会重新被执行。
实现了re-run failed case之后,也有另外一个问题跟我的需求不符合,重新执行过失败的test method之后,testng给出的test result中,把failed cases标记为了skipped,比如一个test method,执行第一次失败,然后retry 3 次,全都失败,testng给出的result就是Total tests run: 4, Failures: 1, Skips: 3.
一共4次失败,前三次都会被标记为skip,只有最后一次被标记为fail。 对于我的需求,我需要将testng result 展现到report中,我期望的result是 run 1 case, failed 1. 所以我后面在ITestListener的实现类的onTestFailure / onTestSuccess方法中,多加了逻辑来处理多余的skipped case。
@Override public void onTestFailure(ITestResult result) { if(CurrentManager.getParameter("retryCount") != null){ ITestNGMethod method = result.getMethod(); while(!result.getTestContext().getSkippedTests().getResults(method).isEmpty()){ result.getTestContext().getSkippedTests().removeResult(method); } } }