1. 概述
本文将探讨如何使用TestNG生成自定义日志和报告。
TestNG自带报告功能,可生成HTML/XML格式的报告。若通过maven-surefire-plugin运行测试,报告将采用插件默认格式。除内置报告外,TestNG还提供了灵活的日志信息和报告生成定制机制。
⚠️ 若需了解TestNG基础,可参考此文。
2. 自定义日志
先看默认日志效果,执行mvn test
命令后输出如下:
Tests run: 11, Failures: 1, Errors: 0, Skipped: 0,
Time elapsed: 1.21 sec <<< FAILURE!
- in TestSuite
whenCalledFromSuite_thanOK(baeldung.com.RegistrationTest)
Time elapsed: 0.01 sec <<< FAILURE!
java.lang.AssertionError: Test Failed due to some reason
at baeldung.com.RegistrationTest.whenCalledFromSuite_thanOK(
RegistrationTest.java:15)
Results :
Failed tests:
RegistrationTest.whenCalledFromSuite_thanOK:15
Test Failed due to some reason
Tests run: 11, Failures: 1, Errors: 0, Skipped: 0
[ERROR] There are test failures.
这些默认日志存在明显缺陷:
- ❌ 缺少测试执行顺序信息
- ❌ 未记录测试开始/结束时间点
- ❌ 无法关联自定义数据
若需获取包含自定义数据的详细执行结果,可通过实现TestNG的监听接口解决。核心方案有两种:
- 实现
org.testng.ITestListener
接口用于日志记录 - 实现
org.testng.IReporter
接口用于报告生成
下面实现一个简单的自定义日志监听器:
public class CustomisedListener implements ITestListener {
// ...
@Override
public void onFinish(ITestContext testContext) {
LOGGER.info("PASSED TEST CASES");
testContext.getPassedTests().getAllResults()
.forEach(result -> {LOGGER.info(result.getName());});
LOGGER.info("FAILED TEST CASES");
testContext.getFailedTests().getAllResults()
.forEach(result -> {LOGGER.info(result.getName());});
LOGGER.info(
"Test completed on: " + testContext.getEndDate().toString());
}
//...
}
关键点说明:
- ✅ 重写
onFinish()
方法,在所有测试完成后触发 - ✅ 同理可重写
onTestStart()
、onTestFailure()
等方法(详见文档)
在XML配置中启用监听器:
<suite name="My test suite">
<listeners>
<listener class-name="com.baeldung.reports.CustomisedListener" />
</listeners>
<test name="numbersXML">
<parameter name="value" value="1" />
<parameter name="isEven" value="false" />
<classes>
<class name="baeldung.com.ParametrizedTests" />
</classes>
</test>
</suite>
执行后输出增强版日志:
...
INFO CUSTOM_LOGS - Started testing on: Sat Apr 22 14:39:43 IST 2017
INFO CUSTOM_LOGS - Testing:
givenNumberFromDataProvider_ifEvenCheckOK_thenCorrect
INFO CUSTOM_LOGS - Tested:
givenNumberFromDataProvider_ifEvenCheckOK_thenCorrect Time taken:6 ms
INFO CUSTOM_LOGS - Testing:
givenNumberObjectFromDataProvider_ifEvenCheckOK_thenCorrect
INFO CUSTOM_LOGS - Failed :
givenNumberObjectFromDataProvider_ifEvenCheckOK_thenCorrect
INFO CUSTOM_LOGS - PASSED TEST CASES
INFO CUSTOM_LOGS - givenNumberFromDataProvider_ifEvenCheckOK_thenCorrect
INFO CUSTOM_LOGS - FAILED TEST CASES
INFO CUSTOM_LOGS -
givenNumberObjectFromDataProvider_ifEvenCheckOK_thenCorrect
INFO CUSTOM_LOGS - Test completed on: Sat Apr 22 14:39:43 IST 2017
...
相比默认日志,自定义版本提供了:
- ✅ 测试执行时间戳
- ✅ 各测试用例的详细状态
- ✅ 失败用例的明确标识
3. 自定义报告
通过maven-surefire-plugin运行测试后,默认在target/surefire-reports
目录生成HTML/XML报告:
若需通过TestNG XML文件执行特定测试套件,需在surefire-plugin配置中指定:
<configuration>
<suiteXmlFiles>
<suiteXmlFile>
src\test\resources\parametrized_testng.xml
</suiteXmlFile>
</suiteXmlFiles>
</configuration>
现在实现自定义报告,核心步骤:
- 实现
org.testng.IReporter
接口 - 重写
generateReport()
方法
public void generateReport(
List<XmlSuite> xmlSuites,
List<ISuite> suites, String outputDirectory) {
String reportTemplate = initReportTemplate();
String body = suites
.stream()
.flatMap(suiteToResults())
.collect(Collectors.joining());
String report
= reportTemplate.replaceFirst("</tbody>", String.format("%s</tbody>", body));
saveReportTemplate(outputDirectory, report);
}
方法参数说明:
xmlSuites
:XML文件中定义的所有测试套件suites
:包含测试执行完整信息的列表对象outputDirectory
:报告生成目录路径
关键实现细节:
initReportTemplate()
:加载HTML模板suiteToResults()
:调用resultsToRow()
生成报告内容saveReportTemplate()
:保存最终报告
核心处理逻辑:
private Function<ISuite, Stream<? extends String>> suiteToResults() {
return suite -> suite.getResults().entrySet()
.stream()
.flatMap(resultsToRows(suite));
}
private Function<Map.Entry<String, ISuiteResult>,
Stream<? extends String>> resultsToRows(ISuite suite) {
return e -> {
ITestContext testContext = e.getValue().getTestContext();
Set<ITestResult> failedTests
= testContext.getFailedTests().getAllResults();
Set<ITestResult> passedTests
= testContext.getPassedTests().getAllResults();
Set<ITestResult> skippedTests
= testContext.getSkippedTests().getAllResults();
String suiteName = suite.getName();
return Stream
.of(failedTests, passedTests, skippedTests)
.flatMap(results ->
generateReportRows(e.getKey(), suiteName, results).stream());
};
}
在XML配置中启用报告器:
<suite name="suite">
<listeners>
<listener class-name="com.baeldung.reports.CustomisedReports" />
</listeners>
<test name="test suite">
<classes>
<class name="baeldung.com.RegistrationTest" />
<class name="baeldung.com.SignInTest" />
</classes>
</test>
</suite>
生成的自定义报告效果:
对比默认surefire报告,自定义报告优势明显:
- ✅ 单表聚合所有测试结果
- ✅ 清晰展示通过/失败/跳过状态
- ✅ 可读性显著提升
4. 总结
本文核心要点:
- TestNG默认日志信息有限,需通过
ITestListener
实现自定义日志 - 默认surefire报告可读性不足,建议通过
IReporter
接口定制 - 自定义方案显著提升测试结果的可追溯性和可读性
💡 深入了解TestNG(如测试用例/套件编写)可参考入门指南
本文所有代码示例可在GitHub仓库中获取。