ExtentReports 结合 TestNg 生成自动化 html 报告 (支持多 suite)
转载:https://testerhome.com/topics/8134
重要说明:报告监听器源码修复一些bug,不再此处更新代码,最新代码可以到github查看最新报告监听器源码
前几天分享了http (s) 接口自动化测试框架 (基于 java),用的是ReportNg来生成报告,@532589730 同学推荐了下extentreport,这几天看了下了解下,做个分享,准备引入到框架中,废话不多说,开始。
说明
- 使用TestNg的Report监听器,不嵌入具体执行代码,仅需在配置文件中新增监听器即可。
- 报告文件生成路径为test-output/index.html。(可在代码中修改)
- 一个suite且一个test配置的情况下,会将执行的用例(method)作为一级节点生成报告。
- 一个suite且多个test配置的情况下,会将每个test配置作为一级节点,执行用例(method)为对应的子节点
- 多个suite的情况下,将suite作为一级节点,test配置为二级节点,执行用例(method)为对应的三级节点。(如果suite下只有一个test配置,则不会生成二级节点,直接把执行的用例(method)生成在第二节点中)
- 代码中使用Report.log("xxx")会将log展示在报告中对应的执行用例(method)中。
- 自动将suite以及test配置的名字作为执行用例(method)的标签。
- 如果用例(method)有参数,则会将调用参数的toString()方法作为用例(method)的名字在报告中显示。
- 已经对执行用例进行按时间排序。(但是多个suite按时间的排序不知道咋处理,求指教。)
代码
pom引用:
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.0.3</version>
</dependency>
创建TestNg的Report监听器:
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.model.TestAttribute;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.configuration.ChartLocation;
import com.aventstack.extentreports.reporter.configuration.Theme;
import org.testng.*;
import org.testng.xml.XmlSuite;
import java.io.File;
import java.util.*;
/**
* Created by chenwx on 17/3/24.
*/
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) {
init();
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