首页 > 编程语言 >走进Java接口测试之TestNg自定报告简单学习

走进Java接口测试之TestNg自定报告简单学习

时间:2023-04-06 15:32:39浏览次数:47  
标签:Java 自定 show overview getName TestNg LogUtil true append

背景

Testng报告是否可以自定义,后面通过查找资料便有了如下自定义报告,testng中提供很多接口,如果需要改造成自己报告只要实现他们的接口即可,以下是根据自己想法实现如下自定义testng报告,如果大家感兴趣,可以根据自己需求修改。也可以把这些数据存储到数据库,之后通过一定规则即可展示出来

走进Java接口测试之TestNg自定报告简单学习_html

注意中间{ echarts.min.js }需要到网上找下放到对应目录即可。

参考代码:

import org.testng.*;
import org.testng.annotations.Test;
import org.testng.reporters.HtmlHelper;
import org.testng.xml.XmlSuite;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * @author 李文
 * @Title: thReporter
 * @Description: 自定义测试报告
 * @date 2019/3/15 / 9:45
 */
publicclassThReporterimplementsIReporter{
/**
     * 获取系统信息
     */
privatestaticProperties sysProperty = System.getProperties();
    
     /**
     * 报告路径
     */
privateString reportPath;
/**
     * 接口类型
     */
privateStringMobile_phone= "SOA层自动化";
/**
     * 版本号
     */
privateString package_name = "2.9.0";
/**  */
/**
     * 通过
     */
privatestaticintPassed= 0;
/**
     * 失败
     */
privatestaticintFailed= 0;
/**
     * 跳过
     */
privatestaticintSkipped= 0;
/**
     * 用例总共合计
     */
privatestaticintCountNum= 0;
/**
     * 通过结果
     */
privatestaticStringPssResuTmp, PassgetName;
/**
     * 开始时间
     */
privatestaticStringStartDate;
/**
     * 结束时间
     */
privatestaticStringEndDate;
/**
     * 描述
     */
privatestaticString description;
/**
     * 客户端类型
     */
privatestaticString clienttype;
/**
     * 拼接报告数据
     */
staticStringBuilder sb1 = newStringBuilder();
@Override
publicvoid generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
       
File htmlReportDir = newFile("test-output/Test-report");
if(!htmlReportDir.exists()) {
            htmlReportDir.mkdirs();
}
String reportName = formateDate() + ".html";
        reportPath = htmlReportDir + "/"+ reportName;
File report = newFile(htmlReportDir, reportName);
if(report.exists()) {
try{
                report.createNewFile();
} catch(IOException e) {
                e.printStackTrace();
}
}
StringBuffer sb = newStringBuffer();
String title = "SOA层自动化";
/**浏览器兼容型添加 http://www.ichartjs.com/ichart.latest.min.js */
        sb.append("<!Doctype >\n<head><meta http-equiv=Content-Type content=\"text/html;charset=utf-8\"><script src='echarts.min.js'></script><meta http-equiv=X-UA-Compatible content=\"IE=edge,chrome=1\"><meta content=always name=referrer><title>UI自动化测试报告</title>")
.append(HtmlHelper.getCssString("."))
.append("</head><body style=\"background-color:#FAEBD7;\">\n")
.append("<h2><p align='center'>").append(title).append("</p></h2>\n")
.append("<table cellspacing='0' cellpadding='0' border='1' width='90%'>")
.append("<tr><th>接口类型</th><th>版本号</th><th><font color=\"#00FF00\">通过数</th><th><font color=\"#FF0000\">失败数</th><th><font color=\"#ADFF2F\">跳过</th><th>用例数 </th><th>类数 </th><th>开始时间 </th><th>结束时间 </th></tr>\n");
String res = sb.toString();
try{
Files.write((Paths.get(reportPath)), res.getBytes("utf-8"));
} catch(IOException e) {
            e.printStackTrace();
}
/**
         * 控制台信息打印
         */
ThReporter.getprintinfotestng(suites);
        sb1.append("<td>"+ Mobile_phone+ "</td><td>"+ package_name + "</td>");
        sb1.append("<td>"+ Passed+ "</td><td>"+ Failed+ "</td><td>"+ Skipped+ "</td><td>"+ (Passed+ Failed+ Skipped) + "</td><td>"+ CountNum+ "</td><td>"+ StartDate+ "</td><td>"+ EndDate+ "</td>\n");
        sb1.append("</table><br/>")
.append("<pre><div id='canvasDiv'></div></pre>")
.append("<pre style=\"text-align:center\"><div id=\"newmain\" style=\"width: 1000px;height:300px; padding-left:50px \"></div></pre>")
.append("<table cellspacing='0' cellpadding='0' border='0' width='90%'>")
.append("<tr><th>"+ "执行用例数:"+ (Passed+ Failed+ Skipped) + "</th></tr>")
.append("</table>")
.append("<tbody style=\"word-wrap:break-word;font-weight:bold;\" align=\"center\"><h2>详 情</h2>")
.append("<table cellspacing='0' cellpadding='0' border='1' width='90%'>");
        sb1.append("<tr><th>序列号 </th><th>失 败</th><th>用例类名</th><th>详情信息</th><th>接口中文名字与验证点</th></tr>\n");
/**详细失败数*/
ThReporter.getFailedpped(suites);
        sb1.append("<tr><th>序列号 </th><th>通 过</th><th>用例类名</th><th>详情信息</th><th>接口中文名字与验证点</th></tr>\n");
/**详细通过数*/
ThReporter.getPassed(suites);
        sb1.append("<tr><th>序列号 </th><th>跳 过</th><th>用例类名</th><th>详情信息</th><th>接口中文名字与验证点</th></tr>\n");
/**
         * 详细跳过数
         */
ThReporter.getskipped(suites);
        sb1.append("</table><br/>");

代码中插入图代码

sb1.append("</tbody></table><a href=\"#top\">SOA层自动化</a></div><script type=\"text/javascript\">\n"+
"    // 基于准备好的dom,初始化echarts实例\n"+
"    var myChart = echarts.init(document.getElementById('newmain'));\n"+
"\n"+
"    // 指定图表的配置项和数据\n"+
"    var option = {\n"+
"        title : {\n"+
"            text: 'SOA层自动化',\n"+
"            subtext: '接口自动化',\n"+
"            x:'center'\n"+
"        },\n"+
"        tooltip : {\n"+
"            trigger: 'item',\n"+
"            formatter: \"{a} <br/>{b} : {c} ({d}%)\"\n"+
"        },\n"+
"        legend: {\n"+
"            text: 'SOA',\n"+
"            x : 'center',\n"+
"            y : 'bottom',\n"+
"            subtext: '333',\n"+
"            // left: 'top',\n"+
"            data:['不通过','通过','跳过']\n"+
"\n"+
"        },\n"+
"        toolbox: {\n"+
"            show : true,\n"+
"            feature : {\n"+
"                mark : {show: true},\n"+
"                dataView : {show: true, readOnly: false},\n"+
"                magicType : {\n"+
"                    show: true,\n"+
"                    type: ['pie', 'funnel']\n"+
"                },\n"+
"                restore : {show: true},\n"+
"                saveAsImage : {show: true}\n"+
"            }\n"+
"        },\n"+
"        calculable : true,\n"+
"        series : [\n"+
"            {\n"+
"                name:'SOA层自动化',\n"+
"                type:'pie',\n"+
"                radius : [30, 110],\n"+
"                center : ['75%', '50%'],\n"+
"                roseType : 'area',\n"+
"                data:[\n"+
"                    {value:"+ Failed+ ",name:'不通过',itemStyle:{color:'#EE0000'}},\n"+
"                    {value:"+ Passed+ ",name:'通过',itemStyle:{color:'#7CFC00'}},\n"+
"                    {value:"+ Skipped+ ",name:'跳过',itemStyle:{color:'#EE9572'}}\n"+
"                ],\n"+
"                itemStyle: {\n"+
"                    emphasis: {\n"+
"                        shadowBlur: 10,\n"+
"                        shadowOffsetX: 0,\n"+
"                        shadowColor: 'rgba(0, 0, 0, 0.5)'\n"+
"                    },\n"+
"                    normal: {\n"+
"                        label: {\n"+
"                            show: true,\n"+
"                            formatter: '{b} : {c} ({d}%)'\n"+
"                        },\n"+
"                        labelLine: {show: true}\n"+
"                    }\n"+
"                }\n"+
"            }\n"+
"            ,{\n"+
"                name:'SOA层自动化',\n"+
"                type:'pie',\n"+
"                radius : [20, 110],\n"+
"                center : ['25%', '50%'],\n"+
"                roseType : 'radius',\n"+
"                label: {\n"+
"                    normal: {\n"+
"                        show: true\n"+
"                    },\n"+
"                    emphasis: {\n"+
"                        show: true\n"+
"                    },\n"+
"                },\n"+
"                lableLine: {\n"+
"                    normal: {\n"+
"                        show: false\n"+
"                    },\n"+
"                    emphasis: {\n"+
"                        show: true\n"+
"                    }\n"+
"                },\n"+
"                data:[{value:"+ Failed+ ",name:'不通过',itemStyle:{color:'#EE0000'}},\n"+
"                    {value:'"+ Passed+ "',name:'通过',itemStyle:{color:'#7CFC00'}},\n"+
"                    {value:"+ Skipped+ ",name:'跳过',itemStyle:{color:'#EE9572'}}],\n"+
"                itemStyle: {\n"+
"                    emphasis: {\n"+
"                        shadowBlur: 10,\n"+
"                        shadowOffsetX: 0,\n"+
"                        shadowColor: 'rgba(0, 0, 0, 0.5)'\n"+
"                    },\n"+
"                    normal: {\n"+
"                        label: {\n"+
"                            show: true,\n"+
"                            formatter: '{b} : {c} ({d}%)'\n"+
"                        },\n"+
"                        labelLine: {show: true}\n"+
"                    }\n"+
"                }\n"+
"            }\n"+
"\n"+
"        ]\n"+
"    };\n"+
"    myChart.setOption(option);\n"+
"\n"+
"</script></body></html>\n");
String res1 = sb1.toString();
try{
Files.write((Paths.get(reportPath)), res1.getBytes("UTF-8"), StandardOpenOption.APPEND);
} catch(IOException e) {
            e.printStackTrace();
}
}

测试类结束控制台显示

/**
     * 控制台信息打印
     */
privatestaticvoid getprintinfotestng(List<ISuite> suites) {
SimpleDateFormat sf = newSimpleDateFormat("yyyy-MM-dd-HH mm-ss");
for(ISuite suite : suites) {
Map<String, ISuiteResult> tests = suite.getResults();
for(ISuiteResult r : tests.values()) {
ITestContext overview = r.getTestContext();
LogUtil.info("suite: "+ overview.getName());
LogUtil.info("Stard Time: "+ sf.format(overview.getStartDate()));
StartDate= sf.format(overview.getStartDate());
LogUtil.info("End Time: "+ sf.format(overview.getEndDate()));
EndDate= sf.format(overview.getEndDate());
CountNum= overview.getAllTestMethods().length;
LogUtil.info("all methods num : "+ overview.getAllTestMethods().length);
//passed
Passed= overview.getPassedTests().size();
LogUtil.info("passed: "+ overview.getPassedTests().size());
Set<ITestResult> passedSet = overview.getPassedTests().getAllResults();
for(ITestResult p : passedSet) {
                    description = p.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description();
LogUtil.info("class: "+ p.getTestClass().getName() + " | method: "+ description);
}
//failed
Failed= overview.getFailedTests().size();
LogUtil.info("failed: "+ overview.getFailedTests().size());
Set<ITestResult> failedSet = overview.getFailedTests().getAllResults();
for(ITestResult f : failedSet) {
LogUtil.info("class: "+ f.getTestClass().getName() + " | method: "+ f.getName() + " | error: "+ f.getThrowable());
}
//skipped
Skipped= overview.getSkippedTests().size();
LogUtil.info("skipped: "+ overview.getSkippedTests().size());
Set<ITestResult> skippedSet = overview.getSkippedTests().getAllResults();
for(ITestResult s : skippedSet) {
LogUtil.info("---- "+ s.getName());
LogUtil.info(s.getThrowable() + "");
}
LogUtil.info("==================================");
}
}
}

跳过方法编写

/**
     * 详细跳过数
     */
publicstaticvoid getskipped(List<ISuite> suites) {
/**详细跳过数*/
for(ISuite suite : suites) {
Map<String, ISuiteResult> tests = suite.getResults();
for(ISuiteResult r : tests.values()) {
ITestContext overview = r.getTestContext();
CountNum= overview.getAllTestMethods().length;
Set<ITestResult> skippedSet = overview.getSkippedTests().getAllResults();
int i = 0;
for(ITestResult s : skippedSet) {
                    description = s.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description();
                    sb1.append("<tr><td>"+ i + "</td><td><font color=\"FF9966\"> 跳过</font></td><td>"+ s.getName() + "</td><td>"+ "接口名字:"+ s.getThrowable() + "</td><td>验证点:"+ description + "</td>");
                                        i++;
}
}
}
}

失败方法编写

/**
     * 详细失败数
     */
publicstaticvoid getFailedpped(List<ISuite> suites) {
for(ISuite suite : suites) {
Map<String, ISuiteResult> tests = suite.getResults();
for(ISuiteResult r : tests.values()) {
ITestContext overview = r.getTestContext();
CountNum= overview.getAllTestMethods().length;
int i = 0;
Set<ITestResult> failedSet = overview.getFailedTests().getAllResults();
for(ITestResult f : failedSet) {
                    description = f.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description();
LogUtil.info("class: "+ f.getTestClass().getName() + " | method: "+ f.getName() + " | error: "+ f.getThrowable());
                    sb1.append("<tr><td>"+ i + "</td><td><font color=\"FF0000\"> 失败</font></td><td>"+ f.getTestClass().getName() + "</td><td>"+ "测试方法名: "+ f.getName() + " 失败详情: "+ f.getThrowable() + "</td><td>验证点:"+ description + "</td>");
                                        i++;
}
}
}

通过方法编写

/**
     * 详细通过数
     */
publicstaticvoid getPassed(List<ISuite> suites) {
for(ISuite suite : suites) {
Map<String, ISuiteResult> tests = suite.getResults();
for(ISuiteResult r : tests.values()) {
ITestContext overview = r.getTestContext();
CountNum= overview.getAllTestMethods().length;
Set<ITestResult> passedSet = overview.getPassedTests().getAllResults();
int i = 0;
for(ITestResult p : passedSet) {
LogUtil.info("class: "+ p.getTestClass().getName() + " | method: "+ p.getName());
PssResuTmp= p.getTestClass().getName();
PassgetName= p.getName();
                    description = p.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).description();
/**获取客户端类型如果安卓、pc版本*/
                    clienttype = p.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName();
                    sb1.append("<tr><td>"+ i + "</td><td><font color=\"#00FF00\"> 通 过</font></td><td>"+ PssResuTmp+ "</td><td>"+ "接口名字:"+ PassgetName+ "</td><td>验证点:"+ description + "</td>");
                                        i++;
}
}
}
}

日期格式化方法

/**
     * 日期格式化
     *
     * @return date
     */
publicstaticString formateDate() {
SimpleDateFormat sf = newSimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
return sf.format(date);
}
/**
     * 日期格式化
     *
     * @return date
     */
privatestaticString formatDate(long date) {
SimpleDateFormat formatter = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return formatter.format(date);
}

监听写好后,通过xml配置即可。

<suitename="First suite"verbose="1">
<listeners>
<listenerclass-name="com.threport.ThReporter"/>
</listeners>
<testname="接口测试报告">
<packages>
<packagename="执行的包名"/>
</packages>
</test>
</suite>

在这里引用屈原《离骚》"路漫漫其修远兮,吾将上下而求索"。

标签:Java,自定,show,overview,getName,TestNg,LogUtil,true,append
From: https://blog.51cto.com/u_15181572/6173352

相关文章

  • JavaScript超大文件上传解决方案:分片断点上传(一)
    ​ 前段时间做视频上传业务,通过网页上传视频到服务器。视频大小小则几十M,大则1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制;2,请求时间过长,请求超时;3,传输中断,必须重新上传导致前功尽弃; 解决方案:1,修改服务端上传的限制配置;Nginx以......
  • Java虚拟机运行时数据区(JVM_2)
    2.3运行时数据区(Run-TImeDataAreas)2.3.1官网概括官网;https://docs.oracle.com/javase/specs/jvms/se8/html/index.htmlTheJavaVirtualMachinedefinesvariousrun-timedataareasthatareusedduringexecutionofaprogram.Someofthesedataareasarecreate......
  • 走进Java接口测试之测试报告ExtentReport
    引言在走进Java接口测试之测试框架TestNG 中我们详细介绍了TestNG的各种用法,在本文中,我将详细介绍如何将ExtentReports测试报告与TestNG集成。ExtentReports简介主要特点:生成的报告简洁美观生成的单html方便Jenkins集成发邮件自带集中展示历史报告的服务端支持Java和.N......
  • 走进Java接口测试之流行框架SpringBoot(概念篇)
    引言说起SpringBoot不得不先了解一下Spring这个企业,不仅因为SpringBoot来源于Spring大家族,而是SpringBoot的诞生和Sping框架的发展息息相关。Spring历史2002年正是JavaEE和EJB大行其道的时候,很多知名公司都是采用此技术方案进行项目开发。一个美国的小伙子Ro......
  • JAVA - 基础篇
    时隔这么久,之前学习JAVA一直没有坚持下来,这次一定要坚持啊。是跟着B站尚硅谷的老师学习的!资料非常齐全,讲得也很认真仔细。这里会记录一些简单的归纳,很全很全的在老师的资料里就有!关注公众号就能领取,尚硅谷教育。前言学习一门计算机语言真的是一件很奇妙的事情,单靠简单的......
  • Java方法
    类,对象,方法 定义方法要加static才能正常引用,详见https://www.bilibili.com/video/BV12J41137hu?p=45&vd_source=7b7ae7eed522b23c0252ec372088c729   Java都是值传递.方法的重载:方法的名字可以相同,参数不相同即可.  可变参数:不定项       ......
  • Map自定义key,然后把value的集合List进行指定字段排序
    packagecom.zdft.purchase;importcom.google.common.collect.Lists;importjava.util.*;importjava.util.stream.Collectors;publicclassStudentMethod{//需求:Map自定义key,然后把value的集合List进行指定字段排序;例如:多次考试,取最高分的集合展示publics......
  • 走进Java接口测试之读取配置文件
    前言但在大部分用例开发环境下,添加额外配置是无所避免的,比如自定义应用端口号、服务地址、数据库的配置等,都或多或少的需要一些外部的配置项等。在前文中我们有详细介绍在接口测试框架中如何基于SpringBoot快速搭建多环境配置,本文将在原有的基础上介绍集成如何快速读取配置文件的......
  • 性能监控之常见 Java Heap Dump 方法
    一、前言在本文中,我们总结下抓Javadump的几种不同方法。JavaHeapDump是特定时刻JVM内存中所有对象的快照。它们对于解决内存泄漏问题和分析Java应用程序中的内存使用情况非常有用。JavaHeapDump通常以二进制格式的hprof文件存储。我们可以使用jhat或JVisualVM之......
  • 1- Java概述
    1.人机交互1.1什么是cmd?就是在windows操作系统中,利用命令行的方式去操作计算机。我们可以利用cmd命令去操作计算机,比如:打开文件,打开文件夹,创建文件夹等。1.2如何打开CMD窗口?按下快捷键:win+R。此时会出现运行窗口。在运行窗口中输出cmd输出回车。解......