import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;
public class KaolaTestListener implements ITestListener {
//用例执行结束后,用例执行成功时调用
public void onTestSuccess(ITestResult tr) {
logTestEnd(tr, "Success");
}
//用例执行结束后,用例执行失败时调用
public void onTestFailure(ITestResult tr) {
logTestEnd(tr, "Failed");
}
//用例执行结束后,用例执行skip时调用
public void onTestSkipped(ITestResult tr) {
logTestEnd(tr, "Skipped");
}
//每次方法失败但是已经使用successPercentage进行注释时调用,并且此失败仍保留在请求的成功百分比之内。
public void onTestFailedButWithinSuccessPercentage(ITestResult tr) {
logTestEnd(tr, "FailedButWithinSuccessPercentage");
}
//每次调用测试@Test之前调用
public void onTestStart(ITestResult result) {
logTestStart(result);
}
//在测试类被实例化之后调用,并在调用任何配置方法之前调用。
public void onStart(ITestContext context) {
return;
}
//在所有测试运行之后调用,并且所有的配置方法都被调用
public void onFinish(ITestContext context) {
return;
}
// 在用例执行结束时,打印用例的执行结果信息
protected void logTestEnd(ITestResult tr, String result) {
Reporter.log(String.format("=============Result: %s=============", result), true);
}
// 在用例开始时,打印用例的一些信息,比如@Test对应的方法名,用例的描述等等
protected void logTestStart(ITestResult tr) {
Reporter.log(String.format("=============Run: %s===============", tr.getMethod()), true);
Reporter.log(String.format("用例描述: %s, 优先级: %s", tr.getMethod().getDescription(), tr.getMethod().getPriority()),
true);
return;
}
}
@Test(description = "demo用例的示例描述", priority = 0)
public void demo() throws IOException, InterruptedException {
Reporter.log("步骤1:调用接口", true);
HttpGetAPI getAPI = new HttpGetAPI();
getAPI.setHost("127.0.0.1");
getAPI.setPort("9999");
getAPI.setPath("/api/sayHello");
getAPI.getUriParams().put("name", "luck");
getAPI.sendRequest(null);
Reporter.log("步骤2:接口调用结果校验", true);
getAPI.verifyResponseStatus(200, "");
}
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/aspectj/aspectjweaver -->
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map;
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.netease.kaola.onlinetest.test.common.ExtentReportsContext; import com.alibaba.fastjson.JSONObject; import com.aventstack.extentreports.ExtentTest; import com.aventstack.extentreports.Status; import org.apache.commons.lang3.StringUtils; public class ExtentTestNGReporter implements IReporter { List groups = new ArrayList(); public void generateReport(List xmlSuites, List suites, String outputDirectory) { for (ISuite suite : suites) { Map result = suite.getResults(); for (ISuiteResult r : result.values()) { ITestContext context = r.getTestContext(); ExtentTest parent = ExtentReportsContext.getInstance().createTest(context.getSuite().getName()); ExtentReportsContext.parentTest.set(parent); buildTestNodes(context.getFailedTests(), Status.FAIL); buildTestNodes(context.getSkippedTests(), Status.SKIP); buildTestNodes(context.getPassedTests(), Status.PASS); for (String group : groups) { ExtentReportsContext.parentTest.get().assignCategory(group); ExtentReportsContext.getInstance().flush(); } groups.clear(); } } for (String s : org.testng.Reporter.getOutput()) { ExtentReportsContext.getInstance().setTestRunnerOutput(s); } } private void buildTestNodes(IResultMap tests, Status status) { if (tests.size() > 0) { for (ITestResult result : tests.getAllResults()) { ExtentTest child = ExtentReportsContext.parentTest.get().createNode(result.getMethod().getMethodName()); ExtentReportsContext.test.set(child); String groupsStr = ""; for (String group : result.getMethod().getGroups()) { if (!groups.contains(group)) { groups.add(group); } if (!StringUtils.isEmpty(groupsStr)) { groupsStr += "|"; } groupsStr += group; ExtentReportsContext.test.get().assignCategory(group); } if (!StringUtils.isEmpty(result.getMethod().getDescription())) { ExtentReportsContext.test.get().log(Status.PASS, String.format("用例描述:%s Priority:%s 分组:%s", result.getMethod().getDescription(), Integer.toString(result.getMethod().getPriority()), groupsStr)); } if (result.getParameters().length > 0) { for (int i = 0; i < result.getParameters().length; i++) { ExtentReportsContext.test.get().log(Status.PASS, "用例参数列表:"); ExtentReportsContext.test.get().log(Status.PASS, String.format("第%d个参数:", i + 1)); ExtentReportsContext.test.get().log(Status.PASS, JSONObject.toJSONString(result.getParameters()[i])); } } ExtentReportsContext.test.get().log(Status.PASS, String.format("=============Run: %s===============", result.getMethod())); List outputs = Reporter.getOutput(result); if (outputs != null) { for (String output : outputs) { ExtentReportsContext.test.get().log(Status.PASS, output); } } if (result.getThrowable() != null) { ExtentReportsContext.test.get().log(status, result.getThrowable()); } ExtentReportsContext.test.get().getModel().setStartTime(getTime(result.getStartMillis())); ExtentReportsContext.test.get().getModel().setEndTime(getTime(result.getEndMillis())); } ExtentReportsContext.getInstance().flush(); } } private Date getTime(long millis) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(millis); return calendar.getTime(); } }
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.ResourceCDN;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.configuration.ChartLocation;
public class ExtentReportsContext {
private static ExtentReports extent;
public static ThreadLocal parentTest = new ThreadLocal();
public static ThreadLocal test = new ThreadLocal();
public static ExtentReports getInstance() {
if (extent == null)
createInstance("接口测试报告.html");
return extent;
}
public static ExtentReports createInstance(String fileName) {
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(fileName);
htmlReporter.config().setTestViewChartLocation(ChartLocation.BOTTOM);
htmlReporter.config().setChartVisibilityOnOpen(true);
// htmlReporter.config().setTheme(Theme.STANDARD);
htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
htmlReporter.config().setDocumentTitle(fileName);
htmlReporter.config().setEncoding("utf-8");
htmlReporter.config().setReportName(fileName);
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
return extent;
}
}
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven.plugins}</version>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<testFailureIgnore>true</testFailureIgnore>
<parallel>false</parallel>
<forkMode>once</forkMode>
<suiteXmlFiles>
<suiteXmlFile>src/main/resources/testng/${run}-${runtype}-testng.xml</suiteXmlFile>
</suiteXmlFiles>
<properties>
<property>
<name>usedefaultlisteners</name>
<value>false</value>
</property>
<property>
<name>listener</name>
<value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter,com.netease.kaola.onlinetest.test.common.ExtentTestNGReporter</value>
</property>
</properties>
<workingDirectory>target/</workingDirectory>
</configuration>
</plugin>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="dubbok_bvt_testsuite" verbose="1" parallel="false">
<test name="dubbok_bvt_testsuite">
<groups>
<run>
<include name="dubbok" />
</run>
</groups>
<packages>
<package name="com.netease.kaola.onlinetest.test.bvt.dubbok.*" />
</packages>
</test>
<listeners>
<listener class-name="com.netease.kaola.onlinetest.test.common.ExtentTestNGReporter" />
<listener class-name="com.netease.kaola.onlinetest.test.common.KaolaTestListener" />
</listeners>
</suite>
package com.netease.kaola.onlinetest.test.base;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Listeners;
import com.netease.kaola.onlinetest.test.common.KaolaTestListener;
@Listeners({ KaolaTestListener.class })
@ContextConfiguration(locations = { "classpath:application.xml" })
public abstract class BaseTest extends AbstractTestNGSpringContextTests {
}
网易云大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者范旭斐授权发布。