使用ExtentReport生成漂亮的测试报告

1.引入依赖

 1         <dependency>
 2             <groupId>com.relevantcodes</groupId>
 3             <artifactId>extentreports</artifactId>
 4             <version>2.41.1</version>
 5         </dependency>
 6
 7         <dependency>
 8             <groupId>com.vimalselvam</groupId>
 9             <artifactId>testng-extentsreport</artifactId>
10             <version>1.3.1</version>
11         </dependency>
12
13         <dependency>
14             <groupId>com.aventstack</groupId>
15             <artifactId>extentreports</artifactId>
16             <version>3.0.6</version>
17         </dependency>    

2.编写测试

 1 public class Demo1 {
 2     @Test
 3     public void test1() {
 4         Assert.assertEquals("aaa", "aaa");
 5     }
 6     @Test
 7     public void test2() {
 8         Assert.assertEquals(1, 2);
 9     }
10
11     @Test
12     public void test3() {
13         Reporter.log("这是我们自己写的日志");
14         throw new RuntimeException("这是我们自己的运行时异常");
15     }
16 }

3.testng.xml配置

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <suite name="我们自己的接口测试套件">
 3     <test name="这些是测试模块">
 4         <classes>
 5             <class name="com.test.testng.Demo1">
 6                 <method>
 7                     <include name="test1"/>
 8                     <include name="test2"/>
 9                     <include name="test3"/>
10                 </method>
11             </class>
12         </classes>
13     </test>
14     <listeners>
15         <listener class-name="com.vimalselvam.testng.listener.ExtentTestNgFormatter"/>
16     </listeners>
17 </suite>

4.解决css无法加载

4.1新建ExtentTestNGIReporterListener实现IReporter,设置静态文件的DNS

  1 import com.aventstack.extentreports.ExtentReports;
  2 import com.aventstack.extentreports.ExtentTest;
  3 import com.aventstack.extentreports.ResourceCDN;
  4 import com.aventstack.extentreports.Status;
  5 import com.aventstack.extentreports.model.TestAttribute;
  6 import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
  7 import com.aventstack.extentreports.reporter.configuration.ChartLocation;
  8 import com.aventstack.extentreports.reporter.configuration.Theme;
  9 import org.testng.*;
 10 import org.testng.xml.XmlSuite;
 11
 12 import java.io.File;
 13 import java.util.*;
 14
 15 public class ExtentTestNGIReporterListener implements IReporter {
 16     //生成的路径以及文件名
 17     private static final String OUTPUT_FOLDER = "test-output/";
 18     private static final String FILE_NAME = "index.html";
 19
 20     private ExtentReports extent;
 21
 22     @Override
 23     public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
 24         init();
 25         boolean createSuiteNode = false;
 26         if(suites.size()>1){
 27             createSuiteNode=true;
 28         }
 29         for (ISuite suite : suites) {
 30             Map<String, ISuiteResult> result = suite.getResults();
 31             //如果suite里面没有任何用例,直接跳过,不在报告里生成
 32             if(result.size()==0){
 33                 continue;
 34             }
 35             //统计suite下的成功、失败、跳过的总用例数
 36             int suiteFailSize=0;
 37             int suitePassSize=0;
 38             int suiteSkipSize=0;
 39             ExtentTest suiteTest=null;
 40             //存在多个suite的情况下,在报告中将同一个一个suite的测试结果归为一类,创建一级节点。
 41             if(createSuiteNode){
 42                 suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName());
 43             }
 44             boolean createSuiteResultNode = false;
 45             if(result.size()>1){
 46                 createSuiteResultNode=true;
 47             }
 48             for (ISuiteResult r : result.values()) {
 49                 ExtentTest resultNode;
 50                 ITestContext context = r.getTestContext();
 51                 if(createSuiteResultNode){
 52                     //没有创建suite的情况下,将在SuiteResult的创建为一级节点,否则创建为suite的一个子节点。
 53                     if( null == suiteTest){
 54                         resultNode = extent.createTest(r.getTestContext().getName());
 55                     }else{
 56                         resultNode = suiteTest.createNode(r.getTestContext().getName());
 57                     }
 58                 }else{
 59                     resultNode = suiteTest;
 60                 }
 61                 if(resultNode != null){
 62                     resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName());
 63                     if(resultNode.getModel().hasCategory()){
 64                         resultNode.assignCategory(r.getTestContext().getName());
 65                     }else{
 66                         resultNode.assignCategory(suite.getName(),r.getTestContext().getName());
 67                     }
 68                     resultNode.getModel().setStartTime(r.getTestContext().getStartDate());
 69                     resultNode.getModel().setEndTime(r.getTestContext().getEndDate());
 70                     //统计SuiteResult下的数据
 71                     int passSize = r.getTestContext().getPassedTests().size();
 72                     int failSize = r.getTestContext().getFailedTests().size();
 73                     int skipSize = r.getTestContext().getSkippedTests().size();
 74                     suitePassSize += passSize;
 75                     suiteFailSize += failSize;
 76                     suiteSkipSize += skipSize;
 77                     if(failSize>0){
 78                         resultNode.getModel().setStatus(Status.FAIL);
 79                     }
 80                     resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize));
 81                 }
 82                 buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL);
 83                 buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP);
 84                 buildTestNodes(resultNode,context.getPassedTests(), Status.PASS);
 85             }
 86             if(suiteTest!= null){
 87                 suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize));
 88                 if(suiteFailSize>0){
 89                     suiteTest.getModel().setStatus(Status.FAIL);
 90                 }
 91             }
 92
 93         }
 94         extent.flush();
 95     }
 96
 97     private void init() {
 98         //文件夹不存在的话进行创建
 99         File reportDir= new File(OUTPUT_FOLDER);
100         if(!reportDir.exists()&& !reportDir .isDirectory()){
101             reportDir.mkdir();
102         }
103         ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
104         // 设置静态文件的DNS
105         //怎么样解决cdn.rawgit.com访问不了的情况
106         htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
107
108         htmlReporter.config().setDocumentTitle("api自动化测试报告");
109         htmlReporter.config().setReportName("api自动化测试报告");
110         htmlReporter.config().setChartVisibilityOnOpen(true);
111         htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
112         htmlReporter.config().setTheme(Theme.STANDARD);
113         htmlReporter.config().setCSS(".node.level-1  ul{ display:none;} .node.level-1.active ul{display:block;}");
114         extent = new ExtentReports();
115         extent.attachReporter(htmlReporter);
116         extent.setReportUsesManualConfiguration(true);
117     }
118
119     private void buildTestNodes(ExtentTest extenttest, IResultMap tests, Status status) {
120         //存在父节点时,获取父节点的标签
121         String[] categories=new String[0];
122         if(extenttest != null ){
123             List<TestAttribute> categoryList = extenttest.getModel().getCategoryContext().getAll();
124             categories = new String[categoryList.size()];
125             for(int index=0;index<categoryList.size();index++){
126                 categories[index] = categoryList.get(index).getName();
127             }
128         }
129
130         ExtentTest test;
131
132         if (tests.size() > 0) {
133             //调整用例排序,按时间排序
134             Set<ITestResult> treeSet = new TreeSet<ITestResult>(new Comparator<ITestResult>() {
135                 @Override
136                 public int compare(ITestResult o1, ITestResult o2) {
137                     return o1.getStartMillis()<o2.getStartMillis()?-1:1;
138                 }
139             });
140             treeSet.addAll(tests.getAllResults());
141             for (ITestResult result : treeSet) {
142                 Object[] parameters = result.getParameters();
143                 String name="";
144                 //如果有参数,则使用参数的toString组合代替报告中的name
145                 for(Object param:parameters){
146                     name+=param.toString();
147                 }
148                 if(name.length()>0){
149                     if(name.length()>50){
150                         name= name.substring(0,49)+"...";
151                     }
152                 }else{
153                     name = result.getMethod().getMethodName();
154                 }
155                 if(extenttest==null){
156                     test = extent.createTest(name);
157                 }else{
158                     //作为子节点进行创建时,设置同父节点的标签一致,便于报告检索。
159                     test = extenttest.createNode(name).assignCategory(categories);
160                 }
161                 for (String group : result.getMethod().getGroups())
162                     test.assignCategory(group);
163
164                 List<String> outputList = Reporter.getOutput(result);
165                 for(String output:outputList){
166                     //将用例的log输出报告中
167                     test.debug(output);
168                 }
169                 if (result.getThrowable() != null) {
170                     test.log(status, result.getThrowable());
171                 }
172                 else {
173                     test.log(status, "Test " + status.toString().toLowerCase() + "ed");
174                 }
175
176                 test.getModel().setStartTime(getTime(result.getStartMillis()));
177                 test.getModel().setEndTime(getTime(result.getEndMillis()));
178             }
179         }
180     }
181
182     private Date getTime(long millis) {
183         Calendar calendar = Calendar.getInstance();
184         calendar.setTimeInMillis(millis);
185         return calendar.getTime();
186     }
187 }

5.修改testng.ml监听器设置

<listeners>
        <listener class-name="com.test.testng.ExtentTestNGIReporterListener"></listener>
    </listeners>

6.再次运行testng.xml,生成报告后,test-output/index.html,得到正常css样式的报告

原文地址:https://www.cnblogs.com/heyuling/p/12069235.html

时间: 2024-10-05 04:27:32

使用ExtentReport生成漂亮的测试报告的相关文章

TestNG+ExtentReports生成超漂亮的测试报告

一个优雅.漂亮的测试报告,能够给我们的测试工作带来不少的加分,而报告的模版实在是让我们这些技术人员头疼的问题,设计的实在是没有什么美感. 那么今天就给大家分享一个自动化测试中,一个超漂亮的测试报告模版. 先展示一下测试报告 那么这个报告是如何生成的呢?简简单单的几步就可以搞定! 1.环境准备 jdkidea或者eclipse都可以maven 2.具体操作     2.1创建一个maven工程     2.2在pom文件中添加 2.3配置你的testng.xml(这里只列出配置,不做仔细讲解,te

extentReport生成测试报告

之前在使用extentReport生成测试报告的时候,没有加载到相关的css,经检查为下面两个文件没有正确加载 后改变配置,加载本地的css和js文件,目前测试报告正确显示 1.创建TestNg的Report监听器,实现方法: private void init() { // TODO Auto-generated method stub File reportDir = new File(OUTPUT_FOLDER); // 文件夹不存在的话进行创建 if (!reportDir.exists

selenium测试报告生成、找到测试报告路径、实现发邮件(整合)

有这样的一个场景: 假设生成的测试报告与多人相关,每个人都去测试服务器査看就会比较麻烦,如果把这种主动的且不及时的査看变成被动且及时的査收,就方便多了. 整个程序的执行过程可以分为三个步骤: ①    通过unittest框架的discover()找到匹配测试用例,由HTMLTestRunner的run()方法执行测试用例并生成最新的测试报告. ②    调用new_report()函数找到测试报告目录(test_case)下最新生成的测试报告,返回测试报告的路径. ③    将得到的最新测试报

.NET生成漂亮桌面背景

.NET生成漂亮桌面背景 一天,我朋友指着某某付费软件对我说,这个东西不错,每天生成一张桌面背景,还能学英语(放置名人名言和翻译)!我说,这东西搞不好我也能做,然后朋友说,"如果你搞出来了,我愿意给你付费$$$$元",然后就有了今天的故事??. 该桌面背景效果如下: 该桌面背景有4个特点: 背景为一张从必应下载的壁纸 英文为随机的名人名言,从API获取 注意文件下文有阴影,使用Direct2D 英文被翻译成了中文,使用了Azure Cognitive Service 当然还有重要的,需

用Pytest+Allure生成漂亮的HTML图形化测试报告

本篇文章将介绍如何使用开源的测试报告生成框架Allure生成规范.格式统一.美观的测试报告. 通过这篇文章的介绍,你将能够: - 将Allure与Pytest测试框架相结合: - 执行测试之后,生成Allure格式的测试报告. 1.Allure测试报告介绍 Allure是一款非常轻量级并且非常灵活的开源测试报告生成框架. 它支持绝大多数测试框架, 例如TestNG.Pytest.JUint等.它简单易用,易于集成.下面就Pytest如何与Allure集成做详细介绍. 2.Pytest框架集成Al

用插件maven-surefire-report-plugin生成html格式测试报告

在默认情况下,执行maven test/maven package/maven install命令时会在target/surefire-reports目录下生成txt和xml格式的输出信息. 其实maven也可以生成html格式的报告,只需要用一个插件即可:maven-surefire-report-plugin. 这个插件的特点: 1.能把生成的xml报告转换成html 2.能指定哪些测试类需要被执行,哪些测试类不被执行 3.能兼容JUnit 3.JUnit 4以及TestNG 4.在默认情况

Jmeter生成html格式测试报告

使用jmeter进行性能测试,运行完毕后生成html格式的测试报告,需要进行如下操作: 1.在C:\apache-jmeter-3.0\bin文件夹下的user.properties文本中添加如下信息: jmeter.save.saveservice.assertion_results_failure_message=true jmeter.save.saveservice.response_code=true jmeter.save.saveservice.response_message=t

Java&amp;Selenium&amp;TestNG&amp;ZTestReport 自动化测试并生成HTML自动化测试报告

一.摘要 本篇博文将介绍如何借助ZTestReport和HTML模版,生成HTML测试报告的ZTestReport 源码Clone地址为 https://github.com/zhangfei19841004/ztest,其中ZTestReport.java 和其template是我们需要的关键. 二.ZTestReport.java 根据我的需要,在源码基础上进行了稍微修改,其中几个注释的地方需要注意,将其集成进自己的自动化框架时需要做相应的修改 package util; import co

Python&amp;Selenium&amp;Unittest&amp;BeautifuReport 自动化测试并生成HTML自动化测试报告

一.摘要 本篇博文将介绍如何借助BeautifulReport和HTML模版,生成HTML测试报告的BeautifulReport 源码Clone地址为 https://github.com/TesterlifeRaymond/BeautifulReport,其中 BeautifulReport.py和其template是我们需要的关键. 二.BeautifulReport 如下代码是BeautifulReport.py的源码,其中几个注释的地方需要注意,将其集成进自己的自动化框架时需要做相应的