概述
Testng 的重试机制 在不写代码的情况没有提供可配置方式,需要自己实现其提供的接口,并以监听器的方式提供出来才可使用,具体步骤如下:
1.首先需要实现 IRetryAnalyzer接口
package ec.qa.autotest.ui.testng.listener;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.Reporter;
import ec.qa.autotest.ui.constants.CommonConstants;
import ec.qa.autotest.ui.testbase.TestBase;
/**
* @author xin.wang
*实现testng接口实现用例失败重跑
*/
public class RetryToRunCase implements IRetryAnalyzer{
private int retryCount = 1;
private static int maxRetryCount;
public int getRetryCount() {
return retryCount;
}
public static int getMaxRetryCount() {
return maxRetryCount;
}
@SuppressWarnings("static-access")
public RetryToRunCase(){
this.maxRetryCount = CommonConstants.RETRY_COUNT;
}
public boolean retry(ITestResult result) {
if (retryCount <= maxRetryCount) {
Reporter.setCurrentTestResult(result);
TestBase.success = false;
retryCount++;
return true;
}
return false;
}
}
2.需要实现testNg监听器的2个接口,onFinish()方法的代码是为了在测试结果报告中剔除掉失败后重试成功的结果.
package ec.qa.autotest.ui.testng.listener;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.testng.IAnnotationTransformer;
import org.testng.IRetryAnalyzer;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.annotations.ITestAnnotation;
/**
* @author xin.wang
* 用例失败重跑的监听器
*/
public class TestngRetryListener implements IAnnotationTransformer,ITestListener {
@SuppressWarnings("rawtypes")
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
IRetryAnalyzer retry = annotation.getRetryAnalyzer();
if (retry == null) {
annotation.setRetryAnalyzer(RetryToRunCase.class);
}
}
public void onFinish(ITestContext testContext) {
ArrayList<ITestResult> testsToBeRemoved = new ArrayList<ITestResult>();
Set<Integer> passedTestIds = new HashSet<Integer>();
for (ITestResult passedTest : testContext.getPassedTests().getAllResults()) {
passedTestIds.add(getId(passedTest));
}
Set<Integer> failedTestIds = new HashSet<Integer>();
for (ITestResult failedTest : testContext.getFailedTests().getAllResults()) {
int failedTestId = getId(failedTest);
if (failedTestIds.contains(failedTestId) || passedTestIds.contains(failedTestId)) {
testsToBeRemoved.add(failedTest);
} else {
failedTestIds.add(failedTestId);
}
}
for (Iterator<ITestResult> iterator = testContext.getFailedTests().getAllResults().iterator(); iterator
.hasNext();) {
ITestResult testResult = iterator.next();
if (testsToBeRemoved.contains(testResult)) {
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 onTestFailure(ITestResult result) {
}
public void onTestStart(ITestResult result) {
// TODO Auto-generated method stub
}
public void onTestSuccess(ITestResult result) {
// TODO Auto-generated method stub
}
public void onTestSkipped(ITestResult result) {
// TODO Auto-generated method stub
}
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
// TODO Auto-generated method stub
}
public void onStart(ITestContext context) {
// TODO Auto-generated method stub
}
}
添加testng监听器的方法很多如下 个人习惯 命令行方式和基于testng的XML文件配置方式:
监听器的使用方法
前文已讲过,监听器的编码过程就是定义一个 Java 类实现监听器接口。下面简单介绍一下监听器的几种使用方法。
在 testng.xml 中使用 TestNG 监听器
TestNG 通过 testng.xml 配置所有的测试方法。Testng.xml 提供了 listeners 和 listener 标签用来添加自定义的监听器。下面示范的是本文示例代码中包含的 testng.xml 文件。
<suite name="TestNGSample"> <listeners> <listener class-name="listeners.OSFilter" /> <listener class-name="listeners.ProgressTracker" /> </listeners> <test name="ProgressTracker Demo"> <classes> <class name="tests.SampleTest" /> </classes> </test> </suite>
在源代码中使用 TestNG 监听器
通过 @Listeners 注释,可以直接在 Java 源代码中添加 TestNG 监听器。下面示范的是本文示例代码中如何使用 @Listeners 注释。
@Listeners({ OSFilter.class, ProgressTracker.class }) public class SampleTest { @Test(groups = { OSNames.OS_LINUX }) public void test1() { sleep(5000); System.out.println(">>>test1"); }
值得注意的是:
- 在 @Listeners 中添加监听器跟在 testng.xml 添加监听器一样,将被应用到整个测试套件中的测试方法。如果需要控制监听器的应用范围(比如添加的监听器仅使用于某些测试测试类或者某些测试方法),则必须在监听器类中编写适当的判断逻辑。
- 在 @Listeners 中添加监听器跟在 testng.xml 添加监听器的不同之处在于,它不能添加 IAnnotationTransformer 和 IAnnotationTransformer2 监听器。原因是因为这两种监听器必须在更早的阶段添加到 TestNG 中才能实施修改注释的操作,所以它们只能在 testng.xml 添加。
- TestNG 对添加的监听器不做去重判断。因此,如果 testng.xml 和源代码中添加了相同的监听器,该监听器的方法会被调用两次。有关这一点,大家可以通过运行本文附带的示例代码包中 testng.xml 验证。因此,切记,不要通过多种方式重复添加监听器。
通过 ServiceLoader 使用 TestNG 监听器
Java SE 6 开始提供了 ServiceLoader。它可以帮助用户查找、加载和使用服务提供程序,从而在无需修改原有代码的情况下轻易地扩展目标应用程序。通过 ServiceLoader 的方式使用 TestNG 监听器,简单来说,就是创建一个 jar 文件,里面包含 TestNG 监听器的实现类已经 ServiceLoader 需要的配置信息,并在运行 TestNG 时把该 jar 文件加载到类路径中。具体步骤请查阅 TestNG 官方文档。这样做的好处是:
- 可以轻松地与其他人分享 TestNG 监听器。
- 当有很多 testng.xml 文件时,不需要重复把监听器添加到每个文件中。
通过命令行使用 TestNG 监听器
通过命令行使用 TestNG 监听器,需要在命令行中加入”-listener”参数。如要指定多个监听器,用逗号分隔。下面是一个调用的示例。
java org.testng.TestNG -listener MyListener testng1.xml [testng2.xml testng3.xml ...]
通过 IDE 使用 TestNG 监听器
TestNG 在多种 IDE 中都有插件支持,比如 Eclipse 和 IDEA。因为最终 IDE 也是以命令行的方式调用 TestNG,因此在 IDE 中也是通过添加“-listener”参数使用 TestNG 监听器。下图以 Eclipse 为例示范了 TestNG 监听器的配置方法。
图 1. Eclipse 中 TestNG 监听器的配置
最后
以上就是顺心招牌为你收集整理的实现testNg的retry机制的全部内容,希望文章能够帮你解决实现testNg的retry机制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复