如何为多Runner类运行的Cucumber多Feature文件生成单一报告?
我来帮你搞定这个问题!你现在每个Feature对应一个继承AbstractTestNGCucumberTests的Runner类,默认每个Runner会生成独立的报告,要合并成一份统一的Cucumber报告,只需要调整配置和添加一点代码就能实现,具体步骤如下:
1. 统一JSON报告的输出路径
首先,给每个Runner类的@CucumberOptions配置指定独立但同目录的JSON报告文件,这样每个Feature的执行结果会生成单独的JSON文件,方便后续合并。
比如LoginRunner的配置:
@CucumberOptions( features = "src/test/resources/features/Login.feature", glue = "com.yourpackage.stepdefs", plugin = { "json:target/cucumber-json-reports/cucumber-login.json", "pretty" } ) public class LoginRunner extends AbstractTestNGCucumberTests { }
CreateAccountRunner的配置类似,只要把JSON文件名改成cucumber-createAccount.json就行,确保所有JSON文件都输出到target/cucumber-json-reports目录下。
2. 自定义SuiteListener实现统一报告生成
你已经在用ISuiteListener,那我们可以扩展它的逻辑,在整个TestNG Suite执行完成后,收集所有JSON报告文件,用ReportBuilder生成统一的HTML报告。
示例代码如下:
import net.masterthought.cucumber.Configuration; import net.masterthought.cucumber.ReportBuilder; import org.testng.ISuite; import org.testng.ISuiteListener; import java.io.File; import java.util.ArrayList; import java.util.List; public class CucumberUnifiedReportListener implements ISuiteListener { @Override public void onFinish(ISuite suite) { // 指定最终统一报告的输出目录 File unifiedReportDir = new File("target/cucumber-unified-report"); // 收集所有cucumber JSON报告文件 List<String> jsonReportPaths = new ArrayList<>(); File jsonDir = new File("target/cucumber-json-reports"); if (jsonDir.exists() && jsonDir.isDirectory()) { for (File jsonFile : jsonDir.listFiles((dir, name) -> name.endsWith(".json"))) { jsonReportPaths.add(jsonFile.getAbsolutePath()); } } // 配置报告的基本信息 Configuration config = new Configuration(unifiedReportDir, "你的项目名称"); // 可以添加自定义分类信息,比如环境、版本号等 // config.addClassifications("测试环境", "UAT"); // config.addClassifications("项目版本", "v1.0.0"); // 生成统一报告 ReportBuilder reportBuilder = new ReportBuilder(jsonReportPaths, config); reportBuilder.generateReports(); } @Override public void onStart(ISuite suite) { // 可选:执行测试前清空旧的报告目录,避免残留文件 File oldReportDir = new File("target/cucumber-unified-report"); if (oldReportDir.exists()) { deleteDir(oldReportDir); } } // 辅助方法:递归删除目录 private boolean deleteDir(File directory) { if (directory.isDirectory()) { File[] files = directory.listFiles(); if (files != null) { for (File file : files) { deleteDir(file); } } } return directory.delete(); } }
3. 配置TestNG.xml统一执行所有Runner
不要单独运行每个Runner类,而是把所有Runner都放到TestNG的suite配置文件里,同时指定我们刚才写的自定义Listener,这样整个Suite执行完成后,Listener会自动触发统一报告的生成。
示例testng.xml:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" > <suite name="Cucumber Unified Test Suite" verbose="1"> <!-- 注册自定义的报告监听器 --> <listeners> <listener class-name="com.yourpackage.listeners.CucumberUnifiedReportListener"/> </listeners> <!-- 登录测试用例 --> <test name="Login Feature Tests"> <classes> <class name="com.yourpackage.runners.LoginRunner"/> </classes> </test> <!-- 创建账号测试用例 --> <test name="Create Account Feature Tests"> <classes> <class name="com.yourpackage.runners.CreateAccountRunner"/> </classes> </test> </suite>
4. 关键注意事项
- 依赖检查:确保你的项目里已经引入了
net.masterthought:cucumber-reporting依赖,比如Maven的pom.xml里要加:
<dependency> <groupId>net.masterthought</groupId> <artifactId>cucumber-reporting</artifactId> <version>5.7.0</version> <!-- 可以用最新稳定版 --> <scope>test</scope> </dependency>
- 执行方式:必须通过TestNG Suite(也就是运行testng.xml)来执行所有测试,不能单独运行每个Runner类,否则Listener不会触发统一报告生成。
- 文件唯一性:每个Runner的JSON报告文件名要唯一,避免被覆盖,最好和Feature名称对应。
这样执行完整个Suite后,你就能在target/cucumber-unified-report目录下看到一份包含所有Feature执行结果的统一Cucumber报告了!
内容的提问来源于stack exchange,提问作者SteroidKing666

