本文 Github/javamap 已收录,有Java程序员进阶技术知识地图以及我的系列文章,欢迎大家Star。

reportng 是一个简单的testng 的生成html格式报告插件,是为了取代testng 默认的生成的报告,reportng提供简单的,多彩的测试结果的视图.

1.首先安装testng

2.下载reportng jar包

http://pan.baidu.com/s/1i3KdlQH

3.添加到project

build path

注意:需要同时引入google guice  http://pan.baidu.com/s/1pJkFezT

4.配置reportng

·  禁用testng default listeners

· 在define listener中添加:org.uncommons.reportng.HTMLReporter

最后run as test suite

在html目录就能看到漂亮的report

如果咋ant里使用,需要这样 :

<testng  classpathref="runpath"  outputDir="test-output"

haltonfailure="true"

useDefaultListeners="false"

listeners="org.uncommons.reportng.HTMLReporter,org.testng.reporters.FailedReporter" >

<xmlfileset dir="${basedir}" includes="Parametertestng.xml"/>

<jvmarg value="-Dfile.encoding=UTF-8" />

<sysproperty key="org.uncommons.reportng.title" value="AutoMation TestReport" />

</testng>

如何修改自定义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框架搭建自动测试框架,经常会需要增加失败自动截图,以及失败重跑功能,下面介绍一下不修改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文件

-- END --

日常求赞:你好技术人,先赞后看养成习惯,你的赞是我前进道路上的动力,对我非常重要。

加油技术人!

简介: 博主从华中科技大学硕士毕业,是一个对技术有追求,对生活有激情的程序员。几年间浪迹于多个一线互联网大厂,具有多年开发实战经验。

微信搜索公众号【爱笑的架构师】,我有技术和故事,等你来。

文章持续更新,在 Github/javamap 中可以看到我归档的系列文章,有面试经验和技术干货,欢迎Star。

用Ant批量运行TestNG测试用例,并配合Reportng实现报告美化相关推荐

  1. Python批量运行Gprmax仿真并快速提取雷达波走时和振幅

    Python批量运行Gprmax仿真并快速提取雷达波走时和振幅 使用gprmax仿真模拟时,通常在cmd窗口写命令,运行结果保存的文件夹不能任意选择,这样很不方便.尤其是在做钻孔电磁波仿真时,需要大量 ...

  2. Postman批量运行

    目录 一.Postman批量运行入口 二.批量运行界面介绍 三.批量运行方式 四.批量运行结果 4.1.批量运行结果列表相关 4.2.批量运行结果视图形式​编辑 一.Postman批量运行入口 二.批 ...

  3. postman批量运行和参数化

    postman批量运行和参数化 1.新建请求,并保存在集合中,需要参数化的参数使用{{参数名}}填写 2.新建csv文件或txt文件,第一列填写参数名,一定要与需要参数化的参数名相同 3.点击集合右侧 ...

  4. Ant批量打包工具的使用

    最近大概用了两天的时间来研究下之前一直好奇的自动批量打包功能 就是利用ant脚本来更改AndroidManifest中的meta渠道值,打包不同的市场渠道号对应下的apk. 之前一直使用的是Eclip ...

  5. IDEA 运行 Junit 测试用例报 !!! JUnit version 3.8 or later expected 错误

    问题介绍 在使用 IDEA 运行 Junit 测试用例的时候,控制台报了!!! JUnit version 3.8 or later expected错误,完整报错信息如下: !!! JUnit ve ...

  6. pytest【运行单个测试用例】

    [pytest框架]运行单个测试用例 单个测试用例函数运行,直接在指定文件后方添加 ::test_name(注意此处两个冒号为英文格式),像下面这样: F:\TESTING\BlogPosts\Rea ...

  7. 简单的android ant 批量打包

    友盟android统计是这样搞的,添加友盟sdk后每打一个平台的包都要修改AndroidManifest.xml里<meta-data android:name="UMENG_CHAN ...

  8. Windows10下配置JavaCup、JFlex及运行JavaCup测试用例

      本文主要是介绍如何在Windows10下下载.配置JavaCup.JFlex及运行JavaCup测试用例.其他博客介绍一种配置JavaCup的方法是:将java-cup-11a.jar的路径添加到 ...

  9. Linux Shell 批量运行语句

    0 基础 Shell本质上就是将多个命令放于*.sh文件中批量运行. 如:新建一个test.sh文件,输入如下几条命令并保存(第一条命令利用同目录下makefile文件编译C++程序,第二条命令删除编 ...

最新文章

  1. JAVA的StringBuffer类
  2. 前端面试之Vue向技巧总结
  3. (转) MiniUI使用
  4. java jframe显示图片_java怎么在JFrame中显示动态图片
  5. Linux中文件上传使用rz
  6. 邮件里面的图怎么复制出来_如何从INS批量导出邮件开发新的客户,推广产品和找reviewer【小技巧】...
  7. 通用mapper和分类实现
  8. Android 应用开发---App 移动应用中九种导航设计总结及其优缺点分
  9. Java数组与容器类分析资料--数组、List和Set、Map-asp.net关注
  10. 转换一个字符串的编码消除乱码
  11. GAN能生成3D图像啦!朱俊彦团队公布最新研究成果
  12. 堆排序(php实现)
  13. python查找文件夹下所有文件_如何用Python实现查找/目录下的文件夹或文件,致谢...
  14. Python标准库:内置函数ascii(object)
  15. python的智能算法_基于pythonQT及智能算法的快速规则定制方法与流程
  16. win10的记事本怎么保存为html,win10系统电脑记事本保存不了的解决办法
  17. 智能优化算法学习总结
  18. 南大计算机系统基础CMU‘s CSAPP——第一章
  19. php里用钢笔画曲线,ps钢笔工具怎么抠图
  20. 2018新年计划-雄起

热门文章

  1. 为什么把鼠标箭头指向任务栏时箭头就没了,根本就不知道箭头在哪
  2. 从零开始的FPGA学习(第一个任务:多数表决器)
  3. python的两种计时方式
  4. 极简视频录制/剪辑工具-Camtasia Studio9
  5. html设置字体仿宋GB2312,Word怎么设置仿宋体显示为仿宋GB2312字体?
  6. shell半自动化部署standalone的spark分布式集群
  7. ZigBee集成开发环境IAR安装
  8. NI的自启动服务的中英对照
  9. 五 Pathon爬虫之抓包与反爬以及反爬解决方案
  10. Java Windows解压缩包代码