1、新建一个Retry 类,implements IRetryAnalyzer接口,这个类里面确定重跑次数,以及分析每次失败是否需要重新运行
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
public class Retry implements IRetryAnalyzer {
private int retryCount = 0;
private int maxRetryCount = 1;
@Override
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;
}
resetRetrycount(); // 每次跑完一条用例后,重置retryCount为0,这样dataProvider 数据驱动测试叶支持
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;
}
public boolean isRetryAvailable() {
return retryCount < maxRetryCount;
}
public void resetRetrycount() {
retryCount = 0;
}
}
2、新建一个RetryListener类,implements IAnnotationTransformer 主要功能是监听事件
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.IRetryAnalyzer;
import org.testng.annotations.ITestAnnotation;
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);
}
}
}
3、测试结果处理,testng运行结果中,去掉重复运行的用例,即不论这个用例跑多少遍,都算一个用例
import java.util.Set;
import org.apache.log4j.Logger;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
public class TestListener implements ITestListener {
private static org.apache.log4j.Logger logger = Logger.getLogger(ITestListener.class);
@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;
}*/
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) {
}
}
4、testng xml中配置监听
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Default suite">
<listeners>
<listener class-name="com.auto.listen1.RetryListener"/>
<listener class-name="com.auto.listen1.TestListener"/>
</listeners>
<test verbose="2" name="Default test">
<classes>
<class name="com.auto.listen1.NewTest"/>
</classes>
</test> <!-- Default test -->
</suite> <!-- Default suite -->
5、新建一个测试类
package com.auto.listen1;
import org.testng.annotations.Test;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
//@Listeners(value = MyTestListenerAdapter.class)
public class NewTest {
@Test(dataProvider = "dp")
// @Test(retryAnalyzer = MyRetryAnalyzer.class,dataProvider = "dp")
public void f(Integer n, String s) {
System.out.println("ssssss:" + s);
Assert.assertFalse(true);
}
}
@DataProvider
public Object[][] dp() {
return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" },new Object[] { 3, "c" },new Object[] { 4, "d" } };
}
}
运行结果:
ssssss:a
Retrying test f with status FAILURE for the 1 time(s).
ssssss:a
ssssss:b
Retrying test f with status FAILURE for the 1 time(s).
ssssss:b
ssssss:b
Retrying test f with status FAILURE for the 1 time(s).
ssssss:b
ssssss:c
Retrying test f with status FAILURE for the 1 time(s).
ssssss:c
ssssss:c
Retrying test f with status FAILURE for the 1 time(s).
ssssss:c
ssssss:c
Retrying test f with status FAILURE for the 1 time(s).
ssssss:c
ssssss:d
Retrying test f with status FAILURE for the 1 time(s).
ssssss:d
ssssss:d
Retrying test f with status FAILURE for the 1 time(s).
ssssss:d
ssssss:d
Retrying test f with status FAILURE for the 1 time(s).
ssssss:d
ssssss:d
Retrying test f with status FAILURE for the 1 time(s).
ssssss:d
这个结果中,第一个参数a运行2遍,第二个参数b运行22=4遍,第三个参数c运行32=6遍,第四个参数d运行4*2=8遍,参数越多运行多余运行次数越多,这个是使用testng 6.9.10 版本问题,更新版本为6.9.13.6 后,运行结果正常如下:
ssssss:a
Retrying test f with status FAILURE for the 1 time(s).
ssssss:a
ssssss:b
Retrying test f with status FAILURE for the 1 time(s).
ssssss:b
ssssss:c
Retrying test f with status FAILURE for the 1 time(s).
ssssss:c
ssssss:d
Retrying test f with status FAILURE for the 1 time(s).
ssssss:d
每个失败用例都重试一次
版本问题参考:https://github.com/cbeust/testng/pull/740
https://github.com/cbeust/testng/pull/1104
转载自:https://www.cnblogs.com/testway/p/6118148.html