testng 提高用例通过率,失败用例要重新运行一次

步骤:

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运行2*2=4遍,第三个参数c运行3*2=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

testng跑失败用例重试的更多相关文章

  1. pytest 失败用例重试

    https://www.cnblogs.com/jinzhuduoduo/articles/7017405.html http://www.lxway.com/445949491.htm https: ...

  2. 【转载】扩展Robot Framework,实现失败用例自动再执行(失败重跑)

    使用自动化脚本进行测试,经常受环境影响等各方面导致本能成功的脚本失败,下面介绍了RFS框架下,失败重跑的方法: 通过改写RobotFramework源代码增加--retry选项,实现test级别的失败 ...

  3. testng增加失败重跑机制

    注: 以下内容引自 http://www.yeetrack.com/?p=1015 testng增加失败重跑机制 Posted on 2014 年 10 月 31 日 使用Testng框架搭建自动测试 ...

  4. testng testcase失败重试

    简单介绍 需求场景:测试移动端应用,常会因为点击失效.网络延迟大等原因导致测试脚本失败.这时,需要自动重新运行失败的脚本,直到脚本成功通过或者到达限定重试次数. 解决方案:实现testng的IRetr ...

  5. RobotFramework与Jenkins集成后失败用例重跑

    Jenkins的执行Windows批处理命令填写如下: call pybot.bat -i 1adsInterface 01_测试用例\接口测试用例\adsInterface.txt call pyb ...

  6. Python接口测试实战4(下) - 框架完善:用例基类,用例标签,重新运行上次失败用例

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  7. 通过Jenkins跑Jmeter接口测试脚本,我想当有接口跑失败时Jenkins发送邮件通知,这个如何弄呢

    通过Jenkins跑Jmeter接口测试脚本,我想当有接口跑失败时Jenkins发送邮件通知,这个如何弄呢

  8. MQ消费失败,自动重试思路

    在遇到与第三方系统做对接时,MQ无疑是非常好的解决方案(解耦.异步).但是如果引入MQ组件,随之要考虑的问题就变多了,如何保证MQ消息能够正常被业务消费.所以引入MQ消费失败情况下,自动重试功能是非常 ...

  9. TestNG监听器实现用例运行失败自动截图、重运行功能

    注: 以下内容引自 http://blog.csdn.net/sunnyyou2011/article/details/45894089 (此非原出处,亦为转载,但博主未注明原出处) 使用Testng ...

随机推荐

  1. MVC三和,你能辨别它?

    上次我们聊的时间MVC,而之前我们学习过三层.那么我们不禁就要问,他们说的是一回事吗.他们有什么联系吗? 三层架构(3-tier application)通常意义上的三层架构就是将整个业务应用划分为: ...

  2. HID Keyboard & Mouse descriptor.

    在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等.USB报告描述符(Report Descriptor)是HID ...

  3. Ajax七层模型用途

    Ajax七层模型 OSI七层模型满足所有网格模型 1.物理层:符合标准: 2.数据链路层:如网卡.水晶头.连接网络层等: 3.网络层:路由器(数据外围打IP地址): 4.传输层:两台计算器端口的连接: ...

  4. hdu 2031

    水题 AC代码: #include<iostream> using namespace std; int main() { int i,j,b[1000],k; while(cin> ...

  5. Python 类 --基础与要点

    1:2.x与3.x区别: 2.x:老式类,都继承自object,继承机制为深度优先 3.x:新式类不需要写(object),继承机制为广度优先 2:类说明: 在定义类下用""&qu ...

  6. (转)根据IP返回对应的位置信息

    其实就是使用了百度的IP库的功能接口,然后处理下就行了,效果图如下: 准备工作: 1.注册成为开度开发者,创建应用获得百度API调用的AK秘钥,百度开发中心地址:http://developer.ba ...

  7. (转)介绍几个C#正则表达式工具

    推荐三个C#正则表达式工具,理由如下 第一个C#正则表达式工具,REGEX 这个C#正则表达式工具优点是中文的,提供了一些示例 第二个C#正则表达式工具,REGEXBUDDY 这是一个真正专业的REG ...

  8. 关于看似简单的eclipse中tomcat小猫图标消失的问题解决

    首先,这个问题出现在我新安装的虚拟机中,自己准备重新搭一套开发环境用于学习. 所以,出于好奇,自己从官网上把eclipse的最新版neo下下来尝尝鲜,刚安装好后发现与之前用的旧版基本相同,于是把相应的 ...

  9. C#操作EXCEL的时候出现“ 无法将类型为“Microsoft.Office.Interop.Excel.ApplicationClass”的COM 对象强制转换为接口类型“Microsoft.Office.Interop.Excel._Application” ”问题

    总是报出这个错误,准备放弃COM的组件转投NPOI,后来想起在装这个操作系统的时候,自带装过WPS,后来使用360卸载了.于是想着试一试的心态,重新安装了WPS,结果,问题解决了.你懂的.

  10. Http服务器性能测试工具ab..

    -A auth-username:password 对服务器提供BASIC认证信任.用户名和密码由一个:隔开,并以base64编码形式发送,无论服务器是否需要(即,是否发送了401认证需求代码),此字 ...