testng跑失败用例重试
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跑失败用例重试的更多相关文章
- pytest 失败用例重试
https://www.cnblogs.com/jinzhuduoduo/articles/7017405.html http://www.lxway.com/445949491.htm https: ...
- 【转载】扩展Robot Framework,实现失败用例自动再执行(失败重跑)
使用自动化脚本进行测试,经常受环境影响等各方面导致本能成功的脚本失败,下面介绍了RFS框架下,失败重跑的方法: 通过改写RobotFramework源代码增加--retry选项,实现test级别的失败 ...
- testng增加失败重跑机制
注: 以下内容引自 http://www.yeetrack.com/?p=1015 testng增加失败重跑机制 Posted on 2014 年 10 月 31 日 使用Testng框架搭建自动测试 ...
- testng testcase失败重试
简单介绍 需求场景:测试移动端应用,常会因为点击失效.网络延迟大等原因导致测试脚本失败.这时,需要自动重新运行失败的脚本,直到脚本成功通过或者到达限定重试次数. 解决方案:实现testng的IRetr ...
- RobotFramework与Jenkins集成后失败用例重跑
Jenkins的执行Windows批处理命令填写如下: call pybot.bat -i 1adsInterface 01_测试用例\接口测试用例\adsInterface.txt call pyb ...
- Python接口测试实战4(下) - 框架完善:用例基类,用例标签,重新运行上次失败用例
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- 通过Jenkins跑Jmeter接口测试脚本,我想当有接口跑失败时Jenkins发送邮件通知,这个如何弄呢
通过Jenkins跑Jmeter接口测试脚本,我想当有接口跑失败时Jenkins发送邮件通知,这个如何弄呢
- MQ消费失败,自动重试思路
在遇到与第三方系统做对接时,MQ无疑是非常好的解决方案(解耦.异步).但是如果引入MQ组件,随之要考虑的问题就变多了,如何保证MQ消息能够正常被业务消费.所以引入MQ消费失败情况下,自动重试功能是非常 ...
- TestNG监听器实现用例运行失败自动截图、重运行功能
注: 以下内容引自 http://blog.csdn.net/sunnyyou2011/article/details/45894089 (此非原出处,亦为转载,但博主未注明原出处) 使用Testng ...
随机推荐
- Android设备中实现Orientation Sensor(图)兼谈陀螺仪
设备中的三自由度Orientation Sensor就是一个可以识别设备相对于地面,绕x.y.z轴转动角度的感应器(自己的理解,不够严谨).智能手机,平板电脑有了它,可以实现很多好玩的应用,比如说指南 ...
- 经常使用ASCII码表(方便查找)
经常使用ASCII码表(方便查找) 键盘 ASCII码 键盘 ASCII码 键盘 ASCII码 键盘 ASCII码 ESC 27 7 55 O 79 g 103 SPACE 32 8 56 P 80 ...
- shell脚本加密
如何保护自己编写的shell程序要保护自己编写的shell脚本程序,方法有很多,最简单的方法有两种:1.加密 2.设定过期时间,下面以shc工具为例说明: 一.下载安装shc工具shc是一个加密s ...
- MySQL加密的性能测试
这是对MySQL进行加密性能测试的两篇文章系列之二.在第一篇中,我专门使用MySQL的内置的对SSL的支持来 做压力测试,产生了一些令人惊讶的结果. AD:WOT2015 互联网运维与开发者大会 热销 ...
- Java static块
首先,我们看一个实际例子: class Test{ public static int X=100; public final static int Y=200; public Test(){ Sys ...
- linux file命令
1. file 是检测文件类型的命令.2. 文件类型就文件组织的方式,通常不同的文件类型执行不同的标准.例如我们熟知的:txt , doc , xls , pdf ...3. file 命令的简单用法 ...
- 免费SVN源代码在线托管
免费的SVN源代码在线托管网站很多,用的最多的是TaoCode吧.但是一般都要求开源,支持私有项目的普遍收费,要不就是流量很少,不够用.对比了一下,发现好库正好能满足需要. 网址: http://ww ...
- border-radius的用法与技巧总结
border-radius属性用法重点罗列 border-radius: none | <length>{1,4} [/<length>{1,4}] ? .如果存在反斜杠/,则 ...
- (转)asp.net实现忘记密码找回的代码
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or ...
- SQL2008转SQL2005数据库经验
1.用SQL2008创建兼容2005的结构脚本. 2.在2005中生成数据库结构. 3.利用2005中的数据导入直接从源数据库中导入数据,此处注意自增长标识的选项需要添加,多表优化选项可以去掉,这里不 ...