需求:一个用例执行失败后再执行几次,避免因为环境不稳定等外部因素引发的失败
代码如下:
- RetryListener
//修改@Test(retry)注解
public class RetryListener implements IAnnotationTransformer {
@Override
public void transform(ITestAnnotation annotation, Class testClass,
Constructor testConstructor, Method testMethod) {
IRetryAnalyzer retry = annotation.getRetryAnalyzer();
if (retry == null) {
annotation.setRetryAnalyzer(TestngRetry.class);
}
}
}
- TestngListener
// 用例级别的监控
public class TestngListener extends TestListenerAdapter {
private static Logger logger = LoggerFactory.getLogger(TestngListener.class);
@Override
public void onTestFailure(ITestResult tr) {
super.onTestFailure(tr);
logger.info(tr.getName() + " Failure");
}
@Override
public void onTestSkipped(ITestResult tr) {
super.onTestSkipped(tr);
logger.info(tr.getName() + " Skipped");
}
@Override
public void onTestSuccess(ITestResult tr) {
super.onTestSuccess(tr);
logger.info(tr.getName() + " Success");
}
// 统计当前已经执行了多少个用例 及状态
@Override
public void onTestStart(ITestResult tr) {
super.onTestStart(tr);
logger.info(tr.getName() + " Start");
ITestContext context = tr.getTestContext();
int passedCount = context.getPassedTests().size();
int faileCount = context.getFailedTests().size();
int skipCount = context.getSkippedTests().size();
int totalCount = passedCount + faileCount + skipCount;
System.out.println("成功个数:" + passedCount);
System.out.println("失败个数:" + faileCount);
System.out.println("跳过个数:" + skipCount);
System.out.println("当前执行总个数:" + totalCount);
}
// 减去失败重试的次数,即使有失败重试,总用例数保持不变
@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;
}
}
- TestngRetry
public class TestngRetry implements IRetryAnalyzer {
private static Logger logger = LoggerFactory.getLogger(TestngRetry.class);
private int retryCount = 1;
private static int maxRetryCount;
static {
//外围文件配置最大运行次数
maxRetryCount = 2;
logger.info("maxRunCount=" + (maxRetryCount));
}
/*
* return true表示没达到最大运行次数,如果执行失败,还会继续重试
* return false表示达到最大运行次数
*/
@Override
public boolean retry(ITestResult result) {
System.out.println("执行结果:" + result.isSuccess());
if (retryCount <= maxRetryCount) {
String message = "running retry for '" + result.getName() + "' on class " +
this.getClass().getName() + " Retrying " + retryCount + " times";
logger.info(message);
Reporter.setCurrentTestResult(result);
Reporter.log("RunCount=" + (retryCount + 1));
retryCount++;
return true;
}
/*
* 同一个测试方法,如果第一条数据重试过了retryCount达到最大,第二条数据就不会再重试,
* 需要把retryCount重新置为1
*/
retryCount=1;
return false;
}
}
- testng.xml
<listeners>
<listener class-name="com.picc.autoTestingWeb.utils.testngUtils.RetryListener" />
</listeners>
注意:使用时加在testng.xml上,不能作为注解加在测试类上
testng官方文档有说明,IAnnotationTransformer只能加在配置文件上
网友评论