接口自动化测试之TestNG测试报告ExtentReports的应用(三)

pom.xml导入包

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6
 7     <groupId>com.TestDemo.www</groupId>
 8     <artifactId>TestDemo</artifactId>
 9     <version>1.0.0</version>
10     <build>
11         <plugins>
12             <plugin>
13                 <groupId>org.apache.maven.plugins</groupId>
14                 <artifactId>maven-compiler-plugin</artifactId>
15                 <configuration>
16                     <source>6</source>
17                     <target>6</target>
18                 </configuration>
19             </plugin>
20         </plugins>
21     </build>
22
23     <dependencies>
24         <dependency>
25             <groupId>org.testng</groupId>
26             <artifactId>testng</artifactId>
27             <version>6.14.3</version>
28         </dependency>
29         <dependency>
30             <groupId>com.relevantcodes</groupId>
31             <artifactId>extentreports</artifactId>
32             <version>2.41.1</version>
33         </dependency>
34         <dependency>
35             <groupId>com.vimalselvam</groupId>
36             <artifactId>testng-extentsreport</artifactId>
37             <version>1.3.1</version>
38         </dependency>
39         <dependency>
40             <groupId>com.aventstack</groupId>
41             <artifactId>extentreports</artifactId>
42             <version>3.0.6</version>
43         </dependency>
44     </dependencies>
45
46 </project>

TestNG测试结果监听代码

  1 package com.testng.config;
  2
  3 import com.aventstack.extentreports.ExtentReports;
  4 import com.aventstack.extentreports.ExtentTest;
  5 import com.aventstack.extentreports.ResourceCDN;
  6 import com.aventstack.extentreports.Status;
  7 import com.aventstack.extentreports.model.TestAttribute;
  8 import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
  9 import com.aventstack.extentreports.reporter.configuration.ChartLocation;
 10 import com.aventstack.extentreports.reporter.configuration.Theme;
 11 import org.testng.*;
 12 import org.testng.xml.XmlSuite;
 13
 14 import java.io.File;
 15 import java.util.*;
 16
 17 public class ExtentTestNGIReporterListener implements IReporter {
 18     //生成的路径以及文件名
 19     private static final String OUTPUT_FOLDER = "test-output/";
 20     private static final String FILE_NAME = "index.html";
 21     private ExtentReports extent;
 22
 23     @Override
 24     public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
 25         init();
 26         boolean createSuiteNode = false;
 27         if(suites.size()>1){
 28             createSuiteNode=true;
 29         }
 30         for (ISuite suite : suites) {
 31             Map<String, ISuiteResult> result = suite.getResults();
 32             //如果suite里面没有任何用例,直接跳过,不在报告里生成
 33             if(result.size()==0){
 34                 continue;
 35             }
 36             //统计suite下的成功、失败、跳过的总用例数
 37             int suiteFailSize=0;
 38             int suitePassSize=0;
 39             int suiteSkipSize=0;
 40             ExtentTest suiteTest=null;
 41             //存在多个suite的情况下,在报告中将同一个suite的测试结果归为一类,创建一级节点。
 42             if(createSuiteNode){
 43                 suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName());
 44             }
 45             boolean createSuiteResultNode = false;
 46             if(result.size()>1){
 47                 createSuiteResultNode=true;
 48             }
 49             for (ISuiteResult r : result.values()) {
 50                 ExtentTest resultNode;
 51                 ITestContext context = r.getTestContext();
 52                 if(createSuiteResultNode){
 53                     //没有创建suite的情况下,将在SuiteResult的创建为一级节点,否则创建为suite的一个子节点。
 54                     if( null == suiteTest){
 55                         resultNode = extent.createTest(r.getTestContext().getName());
 56                     }else{
 57                         resultNode = suiteTest.createNode(r.getTestContext().getName());
 58                     }
 59                 }else{
 60                     resultNode = suiteTest;
 61                 }
 62                 if(resultNode != null){
 63                     resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName());
 64                     if(resultNode.getModel().hasCategory()){
 65                         resultNode.assignCategory(r.getTestContext().getName());
 66                     }else{
 67                         resultNode.assignCategory(suite.getName(),r.getTestContext().getName());
 68                     }
 69                     resultNode.getModel().setStartTime(r.getTestContext().getStartDate());
 70                     resultNode.getModel().setEndTime(r.getTestContext().getEndDate());
 71                     //统计SuiteResult下的数据
 72                     int passSize = r.getTestContext().getPassedTests().size();
 73                     int failSize = r.getTestContext().getFailedTests().size();
 74                     int skipSize = r.getTestContext().getSkippedTests().size();
 75                     suitePassSize += passSize;
 76                     suiteFailSize += failSize;
 77                     suiteSkipSize += skipSize;
 78                     if(failSize>0){
 79                         resultNode.getModel().setStatus(Status.FAIL);
 80                     }
 81                     resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize));
 82                 }
 83                 buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL);
 84                 buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP);
 85                 buildTestNodes(resultNode,context.getPassedTests(), Status.PASS);
 86             }
 87             if(suiteTest!= null){
 88                 suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize));
 89                 if(suiteFailSize>0){
 90                     suiteTest.getModel().setStatus(Status.FAIL);
 91                 }
 92             }
 93
 94         }
 95         extent.flush();
 96     }
 97
 98     private void init() {
 99         //文件夹不存在的话进行创建
100         File reportDir= new File(OUTPUT_FOLDER);
101         if(!reportDir.exists()&& !reportDir .isDirectory()){
102             reportDir.mkdir();
103         }
104         ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
105         // 设置静态文件的DNS
106         //怎么样解决cdn.rawgit.com访问不了的情况
107         htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
108         htmlReporter.config().setDocumentTitle("自动化测试报告");
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 }

运行上一节文章的testng.xml, 会输出一个测试报告, 在浏览器中打开输出的测试报告index.html

原文地址:https://www.cnblogs.com/andrew209/p/9160748.html

时间: 2024-10-13 10:37:45

接口自动化测试之TestNG测试报告ExtentReports的应用(三)的相关文章

Java接口自动化测试之HTTPClient学习(四)

pom.xml  文件中dependency 1 <dependencies> 2 <dependency> 3 <groupId>org.testng</groupId> 4 <artifactId>testng</artifactId> 5 <version>6.14.3</version> 6 </dependency> 7 <dependency> 8 <groupId&g

python WEB接口自动化测试之requests库详解

1.Get请求 前提: requests库是python的第三方库,需要提前安装哦,可以直接用pip命令:`python –m pip install requests` 按照惯例,先将requests库的属性打印出来,看看哪些属性. >>> import requests >>> dir(requests) #查看requests库的属性 ['ConnectionError', 'HTTPError', 'NullHandler', 'PreparedRequest'

Java接口自动化测试之集成MyBatis和MySQL (五)

pom.xml新增dependency 1 <dependency> 2 <groupId>org.mybatis</groupId> 3 <artifactId>mybatis</artifactId> 4 <version>3.4.4</version> 5 </dependency> 6 <dependency> 7 <groupId>mysql</groupId> 8

java 接口自动化测试之数据请求的简单封装

我们自己用java写接口自动化测试框架或者做个接口自动化测试平台的话,是需要自己进行相关的请求的,因此我们需要简单的封装下httpclient,我新建了一个http工具类,将get方法和post方法进行了一个简单的封装. 如果是开发的话,比如APP开发,无论是iOS还是Android,是需要将数据请求进行十分严密的封装的,因为需要对各种网络状态,请求状态做相应的判断处理,因为需要通过这些判断来做出相应的UI交互界面来给用户提示,那么我们做接口测试的话是不需要这么严密的,因为测试的前提就是要保证测

接口自动化测试之PHPUnit-框架代码编写2

接着上篇文章继续代码的讲解,上次的代码中引入了require.php,这个玩意是干啥的呢,今天我们就来说下 require.php内容如下 <?php //所需要的所有引入文件都放这里,方便统一管理,以后的php文件里只需要引入这一个就ok了 //请求相关 require_once("../commons/transfer.php"); //读取配置文件相关 require_once("../src/read_config.php"); //测试用例类相关 r

接口自动化测试之PHPUnit-完结以及源码发放

通过连续的几篇文章一个基本的测试框架就搞定了,是不是觉得很简单?其实写代码这件事情很多时候是我们自己把自己吓到了,只要你愿意去尝试并坚持,一切都会变得自然而然. 当然我们的这个系列文章也是引导大家入门的,本框架还可以继续去完善加强,剩余的就留给大家了. 对了,可能有的朋友会在内心呼喊,这个是phpunit的,如果是其他语言的怎么写啊.嗯,其实都一样,框架这个玩意思想是通用的,就好比奥迪是车,宝马是车,都是四个轮子....你懂的 最后,放出全部源码,获取方式如下: 1.点击链接加入群 522720

接口自动化:HttpClient + TestNG + Java(一) - 接口测试概述+自动化环境搭建

1.1 接口测试简介 1.1.1 什么是接口测试 开始学习接口自动化测试之前,我们先要来了解什么是接口,以及什么是接口测试. 我们都知道,测试从级别上划分可以分为 组件测试 集成测试 系统测试 验收测试 其中在集成测试这个阶段,一个最主要的测试活动就是接口测试.在组件测试中,我们对单个组件自身的功能性能等指标进行验证,上升到集成测试级别,我们则进一步去验证组件之间的交互和集成.而组件之间的交互,就是通过'接口'来达成的.所以一定程度上,集成测试和接口测试概念是大幅度重叠的.(就组件集成/接口测试

python+requests接口自动化完整项目设计源码

前言 有很多小伙伴吵着要完整的项目源码,完整的项目属于公司内部的代码,这个是没法分享的,违法职业道德了,就算别人分享了,也只适用于本公司内部的业务. 所以用例的代码还是得自己去一个个写,我只能分享项目框架,只能帮你们到这了. 一.项目结构 1.新建一个工程(一定要创建工程),工程名称自己定义,如:yoyo_jiekou 2.在工程的跟目录新建一个脚本:run_main.py,用来执行全部用例 3.在工程下创建以下几个pakage包: --case:这个包放test开头的测试用例,也可以放一些封装

零成本实现接口自动化测试 – Java+TestNG 测试Restful service

本文是转载Wade Xu的文章http://www.cnblogs.com/wade-xu/p/4229805.html 接口自动化测试 – Java+TestNG 测试 Restful Web Service 关键词:基于Rest的Web服务,接口自动化测试,数据驱动测试,测试Restful Web Service, 数据分离,Java+Maven+TestNG 本文主要介绍如何用Java针对Restful web service 做接口自动化测试(数据驱动),相比UI自动化,接口自动化稳定性