我们通过重写testng的retry方法和transform方法来实现用例失败重跑的功能。

首先添加两个文件

TestngRetry.java

public class TestngRetry implements IRetryAnalyzer {
private static Logger logger = Logger.getLogger(TestngRetry.class);
private static int maxRetryCount = 3;
private int retryCount = 1; @Override
public boolean retry(ITestResult result) {
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;
}
return false;
}
}

RetryListener.java

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);
}
}
}

添加以上两个文件之后,有两种方法可以使用我们的listener进行监听:

在Test标签中添加retryAnalyzer属性

@Test(retryAnalyzer = com.xxx.retry.RetryListener.class)
  • 在testng.xml文件中配置listener
<test name="test1">
<listeners>
<listener class-name="com.xxx.retry.RetryListener" />
<classes>
<class name="com.xxx.test.NewTest" />
</classes>
</test>

做完上面的工作,我们就可以实现失败重跑的功能了。但是,每次用例重跑之后,每次失败的结果也记录在运行结果中了,测试结果中运行的用例数增加了,不利于我们查看测试结果。因此,我们还需要把重复的用例去掉。 
这个我们通过重写TestListenerAdapter中的onFinish方法实现:

TestngListener.java

public class TestngListener extends TestListenerAdapter {
private static Logger logger = Logger.getLogger(TestngListener.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());
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;
}
}

把listener添加到testng.xml中,当前testng.xml为:

<test name="test1">
<listeners>
<listener class-name="com.xxx.retry.RetryListener" />
<listener class-name="com.xxx.retry.TestngListener" />
</listeners>
<classes>
<class name="com.xxx.test.NewTest" />
</classes>
</test>

OK,结束。

testng执行用例失败,再次执行的更多相关文章

  1. testng对执行失败的用例,再次执行

    前段时间在网络上看到通过重写TestNG的接口,可以再次执行失败的测试用例,于是学习了,我之前的做法是当自己的脚本中碰到异常,就自动调用方法本身来达到再次执行用例的目的,这个过程中有设定重试的次数 对 ...

  2. 如何解决testng执行用例失败自动重跑问题

    注: 以下内容引自 http://blog.csdn.net/MenofGod/article/details/72846649 看过几个相关问题的帖子,内容类似,不过这篇解决问题的步骤和代码比较清晰 ...

  3. 执行testng appium用例失败,自动截图

    新建一个截图监听类ScreenShotListener ,重写onTestFailure方法,里面定义了 监听的driver ,截图文件路径和名称 package com.fsssc.htsgl.ut ...

  4. HTMLTestRunner 汉化版---来源一个大神的源码(加了失败截图,用例失败重新执行 功能)

    HTMLTestRunner 汉化版 20170925 测试报告完全汉化,包括错误日志的中文处理 针对selenium UI测试增加失败自动截图功能 增加失败自动重试功能 增加饼图统计 同时兼容pyt ...

  5. robot:当用例失败时执行关键字(发送短信)

    使用场景: 当用例失败时需要通知对应人员,则需要在Teardown中,使用关键字Run Keyword If Test Failed Send Message关键字为自定义关键字,${content} ...

  6. Python + Appium 【已解决】driver(session)在多个class之间复用,执行完一个类的用例,再次执行下个类的用例时不需要初始化

    实现效果:打开App进行自动化测试,只需打开APP一次,按先后顺序执行n个py文件中的相应操作,实现自动化测试. 示例:如截图示例,一个App,根据此APP内不同的模块,写成了不同的py文件, 预期结 ...

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

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

  8. TestNG设置用例循环执行

    曾经做过一需求,需要单个集成测试用例循环执行N次,或许你会说for循环就可以了,这当然是可以的.那有没有逼格更高点的方法,当然也是有的.下面我们就说下使用TestNG注解功能实现用例的循环执行. 1. ...

  9. Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh

    Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh前,要先清除之前的crs配置信息 # /u01/app/11.2.0/grid/crs/install/rootcr ...

随机推荐

  1. JS animate动画

    <!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8&qu ...

  2. delphi JPG或BMP图片透明显示

    procedure SaveBmpAsIcon(const Bmp: TBitmap; const Icon: string; const SmallIcon: Boolean; const Tran ...

  3. 异步查询json传日期格式到前台,变成了时间戳的格式

    问题: 使用mybatis 查询mysql数据库,其中一个日期格式的字段,由异步查询使用 json传递到前台,变成了时间戳,而不是日期格式了.如何使查询出的日期展示成日期格式呢 解决办法: 1.尝试使 ...

  4. (转)CS0016: 未能写入输出文件

    转自:http://www.pageadmin.net/article/20130305/537.html 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息 ...

  5. 【uoj7】 NOI2014—购票

    http://uoj.ac/problem/7 (题目链接) 题意 给出一棵有根树,每次从一个节点出发可以买票到达它的一定范围内的祖先.问对于每一个点,到达根的最小花费是多少. Solution 右转 ...

  6. 异步IO的并发能力:backlog的配置很重要

    今天中午正准备完工的时候,发现一个让人抓狂的问题. 一个精简版的AIO应用理论上应该比一个完整版的AIO应用并发能力高一些(因为完整版的事务处理复杂一些),在同一台机器上测试. 但测试结果显示,精简版 ...

  7. phpstorm 配置 webpack @ 别名跳转

    webstorm中专门有webpack的相关配置,默认的路径直接是项目根目录下的 webpack.config.js,但是我们用各种cli生成的项目中,webpack的配置一般都是在build下,导致 ...

  8. gdb调试2—单步执行和跟踪函数

    int add_range(int low, int high); int main(int argc, char *argv[]) { int result[100]; result[0] = ad ...

  9. Python【unittest】模块

    [unittest]模块是python3.5中的一个内置模块 1.python文件导入[unittest]模块 import unittest 2.定义一个测试用例类,继承[unittest.Test ...

  10. jquery使用ajax

    前端jquery使用ajax的几种方法: $.ajax使用: $.ajax({ url:'/test_ajax', #发送url data:{a:,b:,csrfmiddlewaretoken:'{{ ...