extentreport部分参考:

  https://blog.csdn.net/Care_sQueendom/article/details/78651950

  https://testerhome.com/topics/8134

extentX(替换为klov)部分参考:

  https://blog.csdn.net/Care_sQueendom/article/details/78651950

  http://extentreports.com/docs/klov/

优化分为两步:

  · extentreport实现客户端美化报告

  · klov实现服务端查看报告

第一步:

· extentreport实现客户端美化报告

用extentreport(客户端)代替原始的testng报告有三种实现方法:

  - 方式一:直接在@BeforeSuite和@BeforeClass进行初始化 
  - 方式二:自己实现testng的ITestListener接口 
  - 方式三:自己实现testng的IReporter接口

只实验了第三种,前两种没有调通,不懂问题出在哪里,忽略不计。同时使用方法2和方法3,会出现直接没有用。

基本操作

1.导入extentReport的pom

 	<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
</dependency>

  有的教程是导入com.relevantcodes,这个似乎是比较旧的2.XX.X的版本,这里使用新的。

2.创建extentreportListener,实现testng的IReporter方法(这个方法负责testng的报告的部分),进行extentreport的报告的设置,包括信息和格式的摆放

  这里代码比较长,基本分为几个部分:

  --初始化extent,设置一些extent的基本值,这里参考的教程的设置htmlreport

  --设置report的suite,case,category的摆放,报告描述的格式,参考了另一个链接,补充了systemInfo部分,本来准备填入手机信息,这里还没有完善

  --extent.flush()

package b.testng.reportRelated;

import java.io.File;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet; import org.testng.IReporter;
import org.testng.IResultMap;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.xml.XmlSuite; import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.ResourceCDN;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.model.SystemAttribute;
import com.aventstack.extentreports.model.TestAttribute;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.configuration.ChartLocation; public class ExtentTestNGIReporterListener implements IReporter{
private static final String OUTPUT_FOLDER = "test-output/";
private static final String FILE_NAME = "index.html";
private ExtentReports extent;
@Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
//给extent初始化,设置初值
initExtent();
boolean createSuiteNode = false;
if(suites.size()>1){
createSuiteNode=true;
}
for (ISuite suite : suites) {
Map<String, ISuiteResult> result = suite.getResults();
//如果suite里面没有任何用例,直接跳过,不在报告里生成
if(result.size()==0){
continue;
}
//统计suite下的成功、失败、跳过的总用例数
int suiteFailSize=0;
int suitePassSize=0;
int suiteSkipSize=0;
ExtentTest suiteTest=null;
//存在多个suite的情况下,在报告中将同一个一个suite的测试结果归为一类,创建一级节点。
if(createSuiteNode){
suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName());
}
boolean createSuiteResultNode = false;
if(result.size()>1){
createSuiteResultNode=true;
}
for (ISuiteResult r : result.values()) {
ExtentTest resultNode;
ITestContext context = r.getTestContext();
if(createSuiteResultNode){
//没有创建suite的情况下,将在SuiteResult的创建为一级节点,否则创建为suite的一个子节点。
if( null == suiteTest){
resultNode = extent.createTest(r.getTestContext().getName());
}else{
resultNode = suiteTest.createNode(r.getTestContext().getName());
}
}else{
resultNode = suiteTest;
}
if(resultNode != null){
resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName());
if(resultNode.getModel().hasCategory()){
resultNode.assignCategory(r.getTestContext().getName());
}else{
resultNode.assignCategory(suite.getName(),r.getTestContext().getName());
}
resultNode.getModel().setStartTime(r.getTestContext().getStartDate());
resultNode.getModel().setEndTime(r.getTestContext().getEndDate());
//统计SuiteResult下的数据
int passSize = r.getTestContext().getPassedTests().size();
int failSize = r.getTestContext().getFailedTests().size();
int skipSize = r.getTestContext().getSkippedTests().size();
suitePassSize += passSize;
suiteFailSize += failSize;
suiteSkipSize += skipSize;
if(failSize>0){
resultNode.getModel().setStatus(Status.FAIL);
}
resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize));
}
buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL);
buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP);
buildTestNodes(resultNode,context.getPassedTests(), Status.PASS);
}
if(suiteTest!= null){
suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize));
if(suiteFailSize>0){
suiteTest.getModel().setStatus(Status.FAIL);
}
} }
// for (String s : Reporter.getOutput()) {
// extent.setTestRunnerOutput(s);
// } extent.flush();
// extent.close();
} private void initExtent() {
//文件夹不存在的话进行创建
File reportDir= new File(OUTPUT_FOLDER);
if(!reportDir.exists()&& !reportDir .isDirectory()){
reportDir.mkdir();
}
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
//TODO 添加时间
htmlReporter.config().setDocumentTitle("zhzh的测试报告");
htmlReporter.config().setReportName("zhzh的测试报告");
htmlReporter.config().setChartVisibilityOnOpen(true);
htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
// htmlReporter.config().setTheme(Theme.STANDARD);
htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
htmlReporter.config().setCSS(".node.level-1 ul{ display:none;} .node.level-1.active ul{display:block;}");
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
extent.setReportUsesManualConfiguration(true);
//TODO 传入mobile的信息
extent.setSystemInfo("uuid", "?");
} private void buildTestNodes(ExtentTest extenttest,IResultMap tests, Status status) {
//存在父节点时,获取父节点的标签
String[] categories=new String[0];
if(extenttest != null ){
List<TestAttribute> categoryList = extenttest.getModel().getCategoryContext().getAll();
categories = new String[categoryList.size()];
for(int index=0;index<categoryList.size();index++){
categories[index] = categoryList.get(index).getName();
}
} ExtentTest test; if (tests.size() > 0) {
//调整用例排序,按时间排序
Set<ITestResult> treeSet = new TreeSet<ITestResult>(new Comparator<ITestResult>() {
@Override
public int compare(ITestResult o1, ITestResult o2) {
return o1.getStartMillis()<o2.getStartMillis()?-1:1;
}
});
treeSet.addAll(tests.getAllResults());
for (ITestResult result : treeSet) {
Object[] parameters = result.getParameters();
String name="";
//如果有参数,则使用参数的toString组合代替报告中的name
for(Object param:parameters){
name+=param.toString();
}
if(name.length()>0){
if(name.length()>50){
name= name.substring(0,49)+"...";
}
}else{
name = result.getMethod().getMethodName();
}
if(extenttest==null){
test = extent.createTest(name);
}else{
//作为子节点进行创建时,设置同父节点的标签一致,便于报告检索。
test = extenttest.createNode(name).assignCategory(categories);
}
//test.getModel().setDescription(description.toString());
//test = extent.createTest(result.getMethod().getMethodName());
for (String group : result.getMethod().getGroups())
test.assignCategory(group); List<String> outputList = Reporter.getOutput(result);
for(String output:outputList){
//将用例的log输出报告中
test.debug(output);
}
if (result.getThrowable() != null) {
test.log(status, result.getThrowable());
}
else {
test.log(status, "Test " + status.toString().toLowerCase() + "ed");
} test.getModel().setStartTime(getTime(result.getStartMillis()));
test.getModel().setEndTime(getTime(result.getEndMillis()));
}
}
} private Date getTime(long millis) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(millis);
return calendar.getTime();
} }

  

3.在testng.xml中配置监听 listener

  步骤2配置了监听,如果单独的执行test用例的类,是无法看到优化的报告的。

  这里需要在xml中配置listener,添加步骤2中的监听,执行testng.xml,就可以看到美化后的报告了。

    <listeners >
<listener class-name="b.testng.reportRelated.ExtentTestNGIReporterListener"/>
</listeners>

  

4.执行testng.xml

  testng.xml的配置使用,可以参考以前的testng相关的博客。

  右键-run as-testng

5.在test-output中打开index.html查看报告

  

第二步:

 用extentX(服务端)查看报告

  我用的mongoDB在本地

1.安装mongoDB,并点击mongod.exe启动

  -下载安装mongoDB

  -启动mongod.exe

2.下载klov并配置properties

  下载链接:http://extentreports.com/community/

  下载的时候你会发现被墙了,自备梯子,或者 https://pan.baidu.com/s/101dV0IbzOYhGLArWJatmpA

  解压zip后得到一个jar,和几个配置文件

  如果mongoDB没有修改过默认端口,就不用修改配置文件。

  需要配置定时执行,或者删除旧的报告,可以按照官网的doc文档进行配置。

  我这里不做修改。

  

3.修改代码

  -使用klov,extentReport最新的版本newer than 3.1.1,如果之前导入的版本低于3.1.1,需要替换;

  -对上面的ExtentTestNGIReporterListener 类的initExtent()方法做修改

    private void initExtent() {
//文件夹不存在的话进行创建
File reportDir= new File(OUTPUT_FOLDER);
if(!reportDir.exists()&& !reportDir .isDirectory()){
reportDir.mkdir();
}
String filePath=OUTPUT_FOLDER + FILE_NAME; ExtentHtmlReporter htmlReporter = createHtmlReporter(filePath);
KlovReporter klovReporter=createKlovReporter(filePath);
extent = new ExtentReports();
extent.attachReporter(htmlReporter,klovReporter);
extent.setReportUsesManualConfiguration(true);
//TODO 传入mobile的信息
extent.setSystemInfo("uuid", "?");
}
//TODO 修改测试报告名称,添加时间
private KlovReporter createKlovReporter(String filePath) {
KlovReporter klovReporter = new KlovReporter();
klovReporter.initMongoDbConnection("localhost",27017);
klovReporter.setKlovUrl("http://localhost:80");
klovReporter.setProjectName("zhzh的project");
klovReporter.setReportName("zhzh的测试报告");
return klovReporter;
} private ExtentHtmlReporter createHtmlReporter(String filePath) {
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(filePath);
//TODO 添加时间
htmlReporter.config().setDocumentTitle("zhzh的测试报告");
htmlReporter.config().setReportName("zhzh的测试报告");
htmlReporter.config().setChartVisibilityOnOpen(true);
htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
// htmlReporter.config().setTheme(Theme.STANDARD);
htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
htmlReporter.config().setCSS(".node.level-1 ul{ display:none;} .node.level-1.active ul{display:block;}");
return htmlReporter;
}

4.进入klov的文件夹,打开命令行执行: java -jar klov-0.1.1.jar

D:\testng\klov-0.1.1>java -jar klov-0.1.1.jar

  

5.运行testng.xml,登录 http://localhost/projects ,选择project后,点击go查看报告

  

testng报告-extentsReports使用-klov的更多相关文章

  1. 优化testng报告

    背景 搞过testng的同学都知道,testng自带的报告非常丑,而且有些字段的展示很不人性化,所以需要优化下报告 解决方案 尝试过一下开源的jar包,如ReportNG,奈何和目前使用的allure ...

  2. 使用extentreports美化testng报告2,增加监听

    有兴趣研究了extentreports报告美化插件,但是因为发现插件有很多内容不能自定义,所以放弃了这个插件,我扩充了官方代码的demo,在testng中增加了监听,并打印了一些测试用例,现在我把两个 ...

  3. [唐胡璐]Selenium技巧- 抓图并保存到TestNG报告中

    这里不讲解怎么在Eclipse安装配置TestNG,网上一搜一大把,大家自己去实践一下。 在这里主要说一下用Java来实现Selenium Webdriver的截图功能和把截图写到TestNG的报告中 ...

  4. testNG报告优化,testNG-xslt

    一.在使用testNG自动化框架执行测试用例后,会自动生成HTML的测试报告,但是过于简单,信息展示极少,也没有图表说明,所有我们使用testNG-xslt进行美化. 二.具体实现步骤: 1.在网站下 ...

  5. 基于testng自动化添加allure报告展示以及jenkins集成

    本地执行方式: 1.下载地址 http://allure.qatools.ru/ 2.执行机器添加环境变量 如mac:vi /etc/profile export ALLURE_HOME=/Users ...

  6. extentsreport testng美化报告生成

    一:主要内容 优化testng测试报告,使用extentsreport 解决extentsreport打开后加载不出来样式的问题 二:报告效果 先上图,看下testng extentsreport报告 ...

  7. APP接口自动化测试JAVA+TestNG(二)之TestNG简介与基础实例

    前言 继上篇环境篇后,本篇主要对TestNG进行介绍,给出最最基础的两个实例,通过本文后,学会并掌握TestNG测试用例的编写与运行,以及生成美化后的报告.下一篇为HTTP接口实战(国家气象局接口自动 ...

  8. Mac Eclipse+Maven+TestNg+ReportNg 生成测试报告

    TestNG 是java 的单元测试框架,功能很强大,很方便,但是自动生成的测试报告有待改善,可以使用TestNg 自带的TestNG_xslt更改TestNG报告的样式,这里主要讲解ReportNg ...

  9. 手把手教你用Eclipse+TestNG搭建接口自动化测试框架

    转载于:http://qa.blog.163.com/blog/static/190147002201510275306185/ 把群博里关于接口自动化的文章都看了一遍,都是关于测试过程中遇到的问题及 ...

随机推荐

  1. 魔术方法:__set、__get

    __set: 在设置对象里边不能直接设置(或没有)的属性值的时候,自动去被调用 class Track { private $track_name; public function __set($na ...

  2. nginx反向代理(动静分离)

    使用反向代理(动静分离)可以让nginx专注静态内容,把动态请求交给apache来处理,发挥各自的优势,而且整个架构更加清晰: 这里假设你已经搭建好了nginx环境; 为了简单起见,就不用源码编译安装 ...

  3. Running Web API using Docker and Kubernetes

    Context As companies are continuously seeking ways to become more Agile and embracing DevOps culture ...

  4. codeforces749B

    Parallelogram is Back CodeForces - 749B 已知平行四边形的三个顶点,求第四个顶点可能的位置.Input输入有三行,每行包括两个整数x和y ( - 1000 ≤ x ...

  5. Nginx 反向代理如何连接上游服务器

    L:92 想上游服务器先建立TCP连接 如三次握手 下面指令可以控制握手时间 proxy_next_upstream  指令当出现502可以换个上游服务器 Tcp keepalive 一般都是由进程在 ...

  6. python数学库math模块

    函数 数学表示 含义 .pi 圆周率π π的近似值,15位小数 .e 自然常数 e e的近似值,15位小数 ceil(x) [x] 对浮点数向上取整 floor(x) [x] 对浮点数向下取整 pow ...

  7. IDEA 根据 Mysql 自动生成

    1 找到 没有的,file--project structure--modules--+--JPA 2  找到如下 添加Mysql连接,记得 Text Connecting一下看看 然后刷新,就可以出 ...

  8. CrawlSpider爬取拉钩

    CrawlSpider继承Spider,提供了强大的爬取规则(Rule)供使用 填充custom_settings,浏览器中的请求头 from datetime import datetime imp ...

  9. 如何简单实现接口自动化测试(基于 python) 原博主地址https://blog.csdn.net/gitchat/article/details/77849725

    如何简单实现接口自动化测试(基于 python) 2017年09月05日 11:52:25 阅读数:9904 GitChat 作者:饿了么技术社区 原文:如何简单实现接口自动化测试(基于 python ...

  10. 【BZOJ4325】【NOIP2015】斗地主 搜索

    题目描述 就是给你一副牌,问你最少几次能出完. 详细规则见规则 \(n\leq 23\) 题解 NOIP的数据非常水,错误一大堆的程序都能AC. 因为顺子对答案的影响最大,所以先枚举顺子进行搜索. 接 ...