ExtentReport5 SparkReporter线程数为1/2时无法生成全部测试报告求助
问题描述
我使用ExtentReporter5生成测试报告时遇到异常:仅当TestNG.xml中的thread-count值等于测试类数量时,spark.html才能生成全部测试报告。比如5个测试类设thread-count=5时报告正常生成,但50+个测试类设thread-count=2时,最终只生成2份报告。请问如何在thread-count=2的情况下生成全部50+测试的完整报告?
示例TestNG.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd"> <suite thread-count="1" parallel="classes" name="BuildAcceptanceTesting - GP"> <listeners> <listener class-name="com.TestUtil.WebEventListener"/> </listeners> <test name ="GP pages"> <classes> <class name="com.byui.gp.StudentSideTest.Test1"/> <class name="com.byui.gp.StudentSideTest.Test2"/> </classes> </test > </suite> <!-- StudentSideTests-Parallel -->
示例代码
base.java
public static WebDriver initialize() { WebDriver contr0l = null; reportingTool(); // Adding extent reporter WebDriverManager.chromedriver().setup(); contr0l = new ChromeDriver(); return contr0l; } public static void reportingTool() { extent = new ExtentReports(); spark = new ExtentSparkReporter("spark.html"); spark.config().setTheme(Theme.STANDARD); spark.config().setDocumentTitle("Report"); extent.attachReporter(spark); } @AfterClass public void closeDriver(WebDriver contr0l) {if(contr0l != null) { contr0l.quit();} } public void FlushExtent(WebDriver contr0l) {extent.flush();}
Test1.java
public class Page1 extends base{ private WebDriver contr0l; @BeforeClass contr0l=base.initialize(); @Test public void TC1(){ System.out.println("whatever");} @Test public void TC2(){ System.out.println("whatever");} @AfterTest public void kapat() { base.FlushExtent(contr0l); base.closeDriver(contr0l); } }
Test2.java
public class Page1 extends base{ private WebDriver contr0l; @BeforeClass contr0l=base.initialize(); @Test public void TC1(){ System.out.println("whatever");} @Test public void TC2(){ System.out.println("whatever");} @AfterTest public void kapat() { base.FlushExtent(contr0l); base.closeDriver(contr0l); } }
解决方案
问题根源
你的代码存在两个核心问题:
- ExtentReports实例重复创建:每个测试类初始化时都会调用
reportingTool(),重新生成ExtentReports和ExtentSparkReporter实例,直接覆盖之前的报告内容。 - 过早调用flush():每个测试类的
@AfterTest阶段就执行extent.flush(),关闭报告文件流,后续线程的测试结果无法写入。
修复步骤
1. 单例模式管理ExtentReports实例
修改base.java,确保全局仅存在一个ExtentReports实例,避免重复创建覆盖报告:
// 改为静态单例变量,仅初始化一次 private static ExtentReports extent; private static ExtentSparkReporter spark; public static WebDriver initialize() { WebDriver contr0l = null; // 懒加载:仅在extent未初始化时创建报告实例 if (extent == null) { reportingTool(); } WebDriverManager.chromedriver().setup(); contr0l = new ChromeDriver(); return contr0l; } public static void reportingTool() { spark = new ExtentSparkReporter("spark.html"); spark.config().setTheme(Theme.STANDARD); spark.config().setDocumentTitle("Report"); extent = new ExtentReports(); extent.attachReporter(spark); }
2. 统一在测试套件结束后刷新报告
移除测试类中@AfterTest里的FlushExtent()调用,改用TestNG监听器在整个套件执行完毕后统一刷新报告:
- 创建监听器类
ExtentReporterListener.java:
public class ExtentReporterListener implements IExecutionListener { @Override public void onExecutionStart() { // 套件启动时初始化报告(可选,也依赖base的懒加载逻辑) if (base.extent == null) { base.reportingTool(); } } @Override public void onExecutionFinish() { // 套件结束时统一写入所有测试结果 if (base.extent != null) { base.extent.flush(); } } }
- 在TestNG.xml中添加该监听器:
<listeners> <listener class-name="com.TestUtil.WebEventListener"/> <listener class-name="com.yourpackage.ExtentReporterListener"/> <!-- 替换为你的包路径 --> </listeners>
3. 调整测试类的清理逻辑
修改测试类的@AfterTest方法,仅关闭WebDriver,不再执行报告刷新:
@AfterTest public void kapat() { base.closeDriver(contr0l); }
关键说明
- 单例模式确保所有测试线程共用同一个报告实例,避免内容被覆盖。
- 套件结束时统一调用
flush(),保证所有线程的测试结果都能写入报告文件。 - ExtentReporter5本身支持线程安全,只要实例唯一,无需额外同步处理。
内容的提问来源于stack exchange,提问作者Deepak Jindal
相关产品推荐
相关产品推荐

