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

使用Testng框架搭建自动测试框架,经常会需要增加失败自动截图,以及失败重跑功能,下面介绍一下不修改Testng的源码,通过监听器的方式来实现自动截图、重跑、以及自定义生成的Html结果文件功能。

自动截图功能
1、新建一个Java类继承TestListenerAdapter
2、重写onTestFailure、onTestSkipped等方法,在这些方法中加入截图操作
3、在testng.xml文件中配置自己编写的监听器类


<listeners>

<listener class-name="***.testng.TestngListener" /> </listeners>


public class TestngListener extends TestListenerAdapter { private static Logger logger = Logger.getLogger(TestngListener.class); public static final String CONFIG = "config.properties"; @Override public void onTestFailure(ITestResult tr) { super.onTestFailure(tr); logger.info(tr.getName() + " Failure"); takeScreenShot(tr); } @Override public void onTestSkipped(ITestResult tr) { super.onTestSkipped(tr); logger.info(tr.getName() + " Skipped"); takeScreenShot(tr); } @Override public void onTestSuccess(ITestResult tr) { super.onTestSuccess(tr); logger.info(tr.getName() + " Success"); } @Override public void onTestStart(ITestResult tr) { super.onTestStart(tr); logger.info(tr.getName() + " Start"); } @Override public void onFinish(ITestContext testContext) { super.onFinish(testContext); } /** * 自动截图,保存图片到本地以及html结果文件中 * * @param tr */ private void takeScreenShot(ITestResult tr) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); String mDateTime = formatter.format(new Date()); String fileName = mDateTime + "_" + tr.getName(); String filePath = OrangeiOS.driver.getScreenshotAs(fileName); Reporter.setCurrentTestResult(tr); Reporter.log(filePath);

//这里实现把图片链接直接输出到结果文件中,通过邮件发送结果则可以直接显示图片 Reporter.log("<img src=\"../" + filePath + "\"/>"); }

失败自动重跑功能
1、新建Java类实现IRetryAnalyzer接口


public class TestngRetry implements IRetryAnalyzer { private static Logger logger = Logger.getLogger(TestngRetry.class); private int retryCount = 1; private static int maxRetryCount; private static ConfigReader config; static {

//外围文件配置最大运行次数 config = new ConfigReader(TestngListener.CONFIG); maxRetryCount = config.getMaxRunCount(); logger.info("maxRunCount=" + (maxRetryCount)); } @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; } }

2、新建Java类实现IAnnotationTransformer接口


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

3、在build.xml或者testng.xml文件中添加RetryListener监听器

上面三步就可以实现失败自动重跑了,是不是比较方便,不过添加了重跑功能后会发现测试结果的邮件中用例的个数增加了,比如我只有一个用例,失败重跑了2次,一共运行3次,测试结果中显示的用例个数会是3个,那接下来就需要解决这个问题了。

首先解决TestNg生成的index.html文件中个数不对的问题,这个问题只需要在Testng监听器的onFinish方法中,等所有用例运行完之后,检查用例,按照class+method+dataprodiver的名称生成hashcode获取唯一id,如果fail的用例中存在重复的则在 fail的用例中剔除掉,具体代码如下:


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

当前失败重跑也存在一些小问题:
1、setup中出现的错误直接是skip的,不会重跑
2、如果存在dataprodiver,则第二组数据以后的用例是不会重跑的
3、testng自带生成的emailable-report.html文件中用例的个数也不对了,这个问题可以自行修改EmailableReporter.java文件

如何修改自定义emailable-report.html

emailable-report.html是Testng运行完成后自动生成的,经常运行结束后我们会把这个文件作为邮件正文发送给收件人,如果我们要修改这个文件内容怎么办呢?

1、首先emailable-report.html文件的生成TestNG是实现了IReporter接口,那我们可以直接从源代码中取出这个文件源代码
https://github.com/cbeust/testng/blob/master/src/main/java/org/testng/reporters/EmailableReporter.java
2、针对源代码进行自己修改
3、把修改后的源代码加入自己的工程
4、在build.xml文件中新增自定义的监听器,运行时就会调用自定义的监听器生成想要的html文件了


<testng outputDir="test-output" classpathref="http://qa.blog.163.com/blog/runpath" haltonfailure="false" listeners="com.****.CustomerEmailableReport" > <xmlfileset dir="." includes="${testngxml}.xml" /> </testng>

TestNG监听器实现用例运行失败自动截图、重运行功能的更多相关文章

  1. TestNG实现用例运行失败自动截图(转载)

    转载自:https://blog.csdn.net/galen2016/article/details/70193684 重写Listener的onTestFailure方法 package com. ...

  2. Selenium2+python自动化67-用例失败自动截图【转载】

    前言: 装饰器其实就是一个以函数作为参数并返回一个替换函数的可执行函数 上一篇讲到用装饰器解决异常后自动截图,不过并没有与unittest结合,这篇把截图的装饰器改良了下,可以实现用例执行失败自动截图 ...

  3. testng 失败自动截图

    testng执行case failed ,testng Listener会捕获执行失败,如果要实现失败自动截图,需要重写Listener的onTestFailure方法 那么首先新建一个Listene ...

  4. QTP场景恢复之用例失败自动截图

    以下代码是在QC里运行QTP来执行脚本过程,当执行过程中发现用例失败后就会自动截图,然后把用例返回到最初始的状态,模拟了场景恢复的机制 Class QCImageErrorCapture Dim qt ...

  5. Webdriver+Testng实现测试用例失败自动截图功能

    testng执行测试用例的时候,如果用例执行失败会自动截图,方便后续排查问题 1.首先定义一个截图类: package com.rrx.utils; import java.io.File;impor ...

  6. TestNG失败自动截图

    转自:https://www.cnblogs.com/tobecrazy/p/4814813.html

  7. appium自动化,失败自动截图

    1.创建监听器类TestNGListener,重写onTestFailure方法,里面定义了 监听的driver ,截图文件路径和名称 package utils; import cases.Appi ...

  8. selenium2入门 断言失败自动截图 (四)

    一般web应用程序出错过后,会抛出异常.这个时候能截个图下来,当然是极好的. selenium自带了截图功能. //获取截图file File scrFile= ((TakesScreenshot)d ...

  9. selenium2 断言失败自动截图 (四)

    一般web应用程序出错过后,会抛出异常.这个时候能截个图下来,当然是极好的. selenium自带了截图功能. //获取截图file File scrFile= ((TakesScreenshot)d ...

随机推荐

  1. Hadoop DataNode不能正常工作的原因

    在把Hadoop环境搭建成功,并且也Hadoop的各个组件都正常工作.在重启过几次Hadoop后发现DataNode不能正常工作,打开Hadoop 的后台http://localhost:50030和 ...

  2. 排序算法入门之希尔排序(java实现)

    希尔排序是对插入排序的改进.插入排序是前面元素已经有序了,移动元素是一个一个一次往后移动,当插入的元素比前面排好序的所有元素都小时,则需要将前面所有元素都往后移动.希尔排序有了自己的增量,可以理解为插 ...

  3. majority element(数组中找出出现次数最多的元素)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  4. GitHub上整理的一些资料

    技术站点 Hacker News:非常棒的针对编程的链接聚合网站 Programming reddit:同上 MSDN:微软相关的官方技术集中地,主要是文档类 infoq:企业级应用,关注软件开发领域 ...

  5. MySQL 8 新特性之Invisible Indexes

    背景 索引是把双刃剑,在提升查询速度的同时会减慢DML的操作.毕竟,索引的维护需要一定的成本.所以,对于索引,要加上该加的,删除无用的.前者是加法,后者是减法.但在实际工作中,大家似乎更热衷于前者,而 ...

  6. SpringBoot使用Maven插件打包部署

    [问题] 之前一直用SpringBoot做一些小项目,想打包部署在环境上,总是少依赖包jar.百度下可以通过Spring Boot Maven plugin插件,把Maven配置的依赖包都打到项目包里 ...

  7. jquery文本框内容实时监控

    $("#A").bind("input propertychange", function () { $("#B").val($(this) ...

  8. spring-mvc报红错误

    can't resolve spring  以及运行测试案例报错 ‘无法找到路径’ 解决办法是在pom文件里面重新配置 对应  resource <resources> <resou ...

  9. super()方法的使用

    如果在子类中也定义了构造器,既_init_()函数,那么基类的构造器该如何调用呢? 方法一.明确指定 使用一个子类的实例去调用基类的构造器,在子类的构造器中明确的指明调用基类的构造器. class C ...

  10. Setting up Latex-vim (or Latex-suite) plugin within macVim under Mac OSX Yosemite 2015-1-20 by congliu

    1. Overview: Vim是命令行下的文本编辑程序,gVim是Vim的Linux下的图形化版本,macVim是Mac下的图形化版本 Latex-vim是vim写Latex文件时的插件 Skim是 ...