testng-报告优化 extentReport
Posted 头鹰在学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了testng-报告优化 extentReport相关的知识,希望对你有一定的参考价值。
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-报告优化 extentReport的主要内容,如果未能解决你的问题,请参考以下文章
TestNG+ExtentReports生成超漂亮的测试报告
接口自动化框架(java)--5.通过testng.xml生成extentreport测试报告