1、idea中生成testNG的单元测试报告:
1.1)下载maven
获得文件:apache-maven-3.8.2-bin.zip
1.1.1)maven配置阿里仓库
在conf/setting.xml中的mirrors下添加mirror子节点
1.1.2)在maven目录下新建本地仓库repository:
将引用包下载到本地仓库\maven\repository
1.2)新建maven项目:untitled_one
1.2.1)idea中配置maven:
File—Settings—Bulid—Bulid Tools—Maven
Maven home path:选择maven解压的路径,如:D:/maven/apache-maven-3.8.2
User settings file:选择配置的Maven仓库,如:D:\maven\apache-maven-3.8.2\conf\settings.xml
Local repository:选择Maven配置的本地仓库,如:D:\maven\repository
1.2.2)maven仓库导入项目:
File—Project Structure—Modules—Dependencies—"+"
—选择(D:\maven\apache-maven-3.8.2与D:\maven\repository)—Apply—OK
1.3)项目的pom.xml文件加入:
1.3.1)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.relevantcodes</groupId>
<artifactId>extentreports</artifactId>
<version>2.41.1</version>
</dependency>
<dependency>
<groupId>com.vimalselvam</groupId>
<artifactId>testng-extentsreport</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.0.6</version>
</dependency>
</dependencies>
</dependencyManagement>
1.3.2)加载pom.xml文件,右键pom.xml文件—Maven—Reload project
1.4)src/java/中新建Package:com.test.test_one
1.5)com.test.test_one包下新建类:Unit_Test_Report
1.6)Test_Ones实现IReporter接口
1.6.1)Unit_Test_Report implements IReporter
1.6.2)选中IReporter(Alt+Enter)点击add maven dependency(import org.testng.IReporter;)
1.6.3)实现报告的路径:
public class Unit_Test_Report implements IReporter {
private static final String OUTPUT_FOLDER = "test-output/";
private static final String FILE_NAME = "test-output/";
private ExtentReports extent;
}
1.6.4)Test_Ones编写init、getTimebuildTestNodes方法,重写generateReport方法(Ctrl+O),代码如下:
package com.test.test_one
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.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.*
public class Unit_Test_Report implements IReporter {
/* 生成报告路径与文件名 */
private static final String OUTPUT_FOLDER = "test-output/"
private static final String FILE_NAME = "index.html"
/* 生成报告情况 */
private ExtentReports extent
/* 初始化报告 */
private void init() {
/* 文件夹不存在时,创建文件夹 */
File reportDir = new File(OUTPUT_FOLDER)
if(!reportDir.exists() && !reportDir.isDirectory()){
reportDir.mkdir()
}
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME)
htmlReporter.config().setDocumentTitle("单元测试报告")
htmlReporter.config().setReportName("单元自动化测试报告")
htmlReporter.config().setChartVisibilityOnOpen(true)
htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP)
htmlReporter.config().setTheme(Theme.DARK)
htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS)
htmlReporter.config().setCSS(".node.level-1 ul{ display:none
extent = new ExtentReports()
extent.attachReporter(htmlReporter)
extent.setReportUsesManualConfiguration(true)
}
/* 报告生成时间 */
private Date getTime(long millis) {
Calendar calendar = Calendar.getInstance()
calendar.setTimeInMillis(millis)
return calendar.getTime()
}
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
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)
}
for (String group : result.getMethod().getGroups()){
test.assignCategory(group)
}
test = extent.createTest(result.getMethod().getMethodName())
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()))
}
}
}
@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.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
}
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
if(suiteFailSize > 0){
suiteTest.getModel().setStatus(Status.FAIL)
}
}
}
for (String s : Reporter.getOutput()) {
extent.setTestRunnerOutput(s)
}
extent.flush()
}
}
1.7)src/main/java/com.test目录下新建Mathematics类
package com.test.modle
public class Mathematics {
public int getFactorial(int num){
int result = 0
if(num == 1){
result = num
}else {
result = getFactorial(num - 1)*num
}
return result
}
}
1.8)src/main/java/com.test目录下新建Test_Test_q类
package com.test.test_modle;
import com.test.modle.Test_q;
import org.testng.annotations.Test;
public class Test_Test_q {
@Test
public void test_print_Test_q_1(){
Test_q test_q = new Test_q();
test_q.print_Test_q();
}
}
1.9)src/test/java/com.test_modle目录下新建Mathematics类(首个测试类一定要加@BeforeSuite与@BeforeClass)
package com.test.test_modle;
import com.test.modle.Mathematics;
import org.testng.Assert;
import org.testng.annotations.*;
public class Test_Mathematics {
@BeforeSuite
public void test_BeforeSuite(){
System.out.println("开始测试modle套件");
}
@AfterSuite
public void test_AfterSuite(){
System.out.println("结束测试modle套件");
}
@BeforeClass
public void test_BeforeClass(){
System.out.println("开始测试Mathematics类");
}
@AfterClass
public void test_AfterClass(){
System.out.println("结束测试Mathematics类");
}
Mathematics mathematics = null;
int num = 0;
@Test
public void test_getFactorial_1(){
mathematics = new Mathematics();
num = mathematics.getFactorial(1);
Assert.assertEquals(num,1);
}
@Test
public void test_getFactorial_2(){
mathematics = new Mathematics();
num = mathematics.getFactorial(5);
Assert.assertEquals(num,1211);
}
}
1.10)src/test/java/com.test_modle目录下新建Test_Test_q类(位于同一目录下所以只需要加@BeforeClass)
package com.test.test_modle;
import com.test.modle.Test_q;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class Test_Test_q {
@BeforeClass
public void test_BeforeClass(){
System.out.println("开始测试Test_Test_q类");
}
@AfterClass
public void test_AfterClass(){
System.out.println("结束测试Test_Test_q类");
}
@Test
public void test_print_Test_q_1(){
Test_q test_q = new Test_q();
test_q.print_Test_q();
}
}
1.11)项目下新建testNG.xml文件,具体文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="modle测试套件">
<test name="测试Mathematics类">
<classes>
<class name="com.test.test_modle.Test_Mathematics">
<methods>
<include name="test_getFactorial_1"/>
<include name="test_getFactorial_2"/>
</methods>
</class>
</classes>
</test>
<test name="测试Test_q类">
<classes>
<class name="com.test.test_modle.Test_Test_q">
<methods>
<include name="test_print_Test_q_1"/>
</methods>
</class>
</classes>
</test>
<listeners>
<listener class-name="com.test.test_one.Unit_Test_Report"></listener>
</listeners>
</suite>
1.12)点击右上角【绿色三角】前的空格Edit Configurations
1.12.1)左上角选择项目,Code Coverage—"+"—选择Mathematics与测试Test_q类—Apply—OK
1.13)生成报告设置:
1.13.1)run——edit Configurations——选择左侧要生成报告的类——Configuration——Listeners——勾选:Use default reporters——点击:OK
1.13.2)报告生成在项目的test-output目录下,由html与xml两种格式报告
1.13.3)右键testNG.xml文件,选择Run '...testNG.xml' with Coverage,查看报告
1.14)一个套件一定要加@BeforeSuite与@AfterSuite,套件下的类一定要加@BeforeClass与@AfterClass