TestNG + extentReports + log4j2 complete automated testing framework - beautiful reports and log files are kept

1: Import Maven dependent
<dependency>
<the groupId> com.aventstack </ the groupId>
<the artifactId> extentreports </ the artifactId>
<Version> 3.0.3 </ Version>
</ dependency>
2: preparation of ExtentTestNGIReporterListener listener
ExtentTestNGIReporterListener listener main used for generating HTMLReport

package Listeners;

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 org.testng.*;
import org.testng.xml.XmlSuite;

import java.io.File;
import java.util.*;

/**
* Created by yangbin on 18/12/10.
*/
public class ExtentTestNGIReporterListener implements IReporter {
// 生成的路径以及文件名
Final static String = OUTPUT_FOLDER Private "the Test-the Output /";
// Notice that using index.html may cause testng the report will cover it
Private Final static String FILE_NAME = "report.html";

Private ExtentReports extent;

@Override
public generateReport void (List <XmlSuite> xmlSuites, List <iSUITE> Suites, the outputDirectory String) {
the init ();
Boolean = createSuiteNode to false;
IF (suites.size ()>. 1) {
createSuiteNode = to true;
}
for (iSUITE Suite: Suites ) {
the Map <String, ISuiteResult> suite.getResults Result = ();
// if there is no use case suite, skip, not report generated
IF (result.size () == 0) {
Continue;
}
// success, failure statistics under Suite, the total number of cases with the skip
int suiteFailSize = 0;
suitePassSize = 0 int;
int suiteSkipSize = 0;
ExtentTest suiteTest = null;
the case where there are a plurality // suite of test result is reported in the same suite of a classified as a class, create a node.
IF (createSuiteNode) {
suiteTest = extent.createTest (suite.getName ()) assignCategory (suite.getName ());.
}
Boolean = createSuiteResultNode to false;
IF (result.size ()>. 1) {
createSuiteResultNode = to true;
}
for (R & lt ISuiteResult: result.values ()) {
ExtentTest resultNode;
ITestContext r.getTestContext context = ();
IF (createSuiteResultNode) {
case // not created suite will create SuiteResult for a node, or the creation of a suite of child nodes.
IF (suiteTest == null) {
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();
}

private void init() {
// 文件夹不存在的话进行创建
File reportDir = new File(OUTPUT_FOLDER);
if (!reportDir.exists() && !reportDir.isDirectory()) {
reportDir.mkdir();
}
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
// 设置静态文件的DNS
// how to solve the case cdn.rawgit.com not visit the
htmlReporter.config () setResourceCDN (ResourceCDN.EXTENTREPORTS);.
HtmlReporter.config () setDocumentTitle ( "API Automated Test Report");.
. HtmlReporter.config () setReportName ( "api automated testing reports");
htmlReporter.config () setChartVisibilityOnOpen (to true);.
// report location
htmlReporter.config () setTestViewChartLocation (ChartLocation.TOP);.
. // htmlReporter.config () setTheme (Theme.STANDARD );
htmlReporter.config () setCSS ( "UL {node.level. 1-the display: none;}. {.node.level UL-1.active the display: Block;}.");
extents ExtentReports new new = ();
extents .attachReporter (htmlReporter);
extent.setReportUsesManualConfiguration (to true);
}

private void buildTestNodes (ExtentTest extenttest, IResultMap tests, Status status) {
// If there is a parent node, a parent node acquires label
String [] = new new String the Categories [0];
IF (! extenttest = null) {
List <the TestAttribute> CategoryList . = extenttest.getModel () getCategoryContext () the getAll ();.
the Categories = new new String [categoryList.size ()];
for (int index = 0; index <categoryList.size (); index ++) {
the Categories [index] = categoryList.get (index) .getName ();
}
}

ExtentTest Test;

IF (tests.size ()> 0) {
// adjustment, sorted by time ordered with Example
Set <ITestResult> treeSet = new TreeSet <ITestResult> (new Comparator <ITestResult> () {
@Override
public int Compare (ITestResult O1, O2 ITestResult) {
o1.getStartMillis return () <o2.getStartMillis () -1:?. 1;
}
});
treeSet.addAll (tests.getAllResults ());
for (ITestResult Result: TreeSet) {
Object [] = result.getParameters Parameters ( );
String name = "";
// if the parameter, the parameter is used in place of the combination of toString report name
for (Object param: parameters) {
name = param.toString + ();
}
IF (name.length () > 0) {
IF (name.length ()> 50) {
name = name.substring (0, 49) + "...";
}
} {the else
. result.getMethod name = () getMethodName ();
}
IF (extenttest == null) {
Test = extent.createTest (name);
} the else {
// when created as a child node, the parent node is provided with the same label, to facilitate retrieval report.
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 (the getTime (result.getEndMillis ()));.
}
}
}

Private a Date the getTime (Long of millis) {
Calendar Calendar Calendar.getInstance = ();
calendar.setTimeInMillis (of millis);
return calendar.getTime ( );
}
}
3: writing test code
Package TestCase;

Import org.testng.Assert;
Import org.testng.Reporter;
Import org.testng.annotations.Test;

/ **
* Case demo
* * /
public class Case1 {

@ the Test
public TestCase1 void () {
// record log log TestNG Report can be displayed as objects in the console comes with built
Reporter.log ( "executing TestCase1", to true);
Assert.assertTrue (to true);
}

@Test
void testCase2 public () {

Reporter.log ( "executing testCase2", to true);
Assert.assertTrue (to false);
}

@Test
public void testCase3 () {

Reporter.log ( "executing testCase3", to true);
the Assert. assertTrue (to true);
}
}
. 4: writing file testNG.xml
4.1: single multiple test suite execution tag
testng.xml profile follows

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name="Listeners.ExtentTestNGIReporterListener"></listener>
</listeners>
<test name="Test1">
<classes>
<!-- Class需要拆开 不然没法写 methods-->
<class name="TestCase.case1">
<methods>
<include name="testCase1"></include>
</methods>
</class>
</classes>
</test> <!-- Test -->
<test name="Test2">
<classes></ Methods><the include name = "testCase2"> </ the include><Methods><class name = "TestCase.case1">
<-! Class need to disassemble or can not write Methods ->




</class>
</classes>
</test> <!-- Test -->
<test name="Test3">
<classes>
<!-- Class需要拆开 不然没法写 methods-->
<class name="TestCase.case1">
<methods>
<include name="testCase3"></include>
</methods>
</class>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
HTMLReport报告样式

 

 

 

4.2: Other
you can also write more and more test suite manner not go into here
----------------
Disclaimer: This article is the original article CSDN bloggers "AnndyTuo" of follow CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
Original link: https: //blog.csdn.net/hujyhfwfh2/article/details/84950119

Guess you like

Origin www.cnblogs.com/liyunfeng111/p/11497900.html