如何在Cucumber中通过TestRunner类生成类HTML格式的Excel测试报告
Cucumber框架生成定制Excel测试报告实现方案
整体基于Cucumber官方的Plugin扩展机制实现,不需要依赖第三方小众报告插件,和TestRunner类无缝集成,生成的报告字段覆盖要求的测试用例状态、执行时间、失败原因、失败场景、失败步骤核心项,展示结构、统计逻辑完全对齐Cucumber原生HTML报告。
前置依赖准备
- 保持项目现有Cucumber Java、Cucumber JUnit版本不变,避免版本兼容问题
- 引入Apache POI依赖用于生成.xlsx格式Excel文件,建议使用5.x稳定版本,不要用3.x老旧版本,避免样式兼容问题
- 不需要额外引入UI类依赖,单元格样式(成功/失败标色、换行、列宽调整)直接用POI自带能力即可实现
<!-- 测试域引入POI依赖即可 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> <scope>test</scope> </dependency>
自定义Excel报告插件
Cucumber原生HTML报告本身就是基于事件监听机制实现的,我们自定义插件实现ConcurrentEventListener接口即可,线程安全支持并行测试,核心监听三类事件:
- TestCaseStarted/TestCaseFinished事件:记录场景启动时间、结束时间,计算单场景执行时长,获取场景最终执行状态,统计值和原生HTML报告完全一致
- TestStepFinished事件:逐步骤记录执行内容、状态,标记失败步骤的具体文本、行号,捕获异常信息
- TestSourceRead事件:记录场景所属Feature文件路径、Feature名称,和原生报告的层级结构对齐
插件内部用线程安全的集合存储所有场景的结果数据,字段映射规则:
- 测试用例状态:直接取Cucumber返回的状态枚举,和原生报告一致分为PASSED/FAILED/SKIPPED/PENDING四类
- 执行时间:用TestCaseStarted记录的时间戳和TestCaseFinished的时间戳做差值,转成秒/毫秒单位,不把@Before/@After钩子的执行时间算入场景耗时,和原生报告统计规则对齐
- 失败原因:捕获失败场景的异常信息,过滤掉Cucumber内部反射调用的冗余栈帧,只保留核心业务报错信息
- 失败场景:存储「Feature名称 + 场景名称 + 场景所在Feature行号」,和原生报告的场景定位信息一致
- 失败步骤:遍历当前场景下所有执行步骤,标记状态为FAILED的步骤,存储步骤文本、传参、行号信息
插件核心代码结构参考:
public class CucumberExcelReportPlugin implements ConcurrentEventListener { private final String excelOutputPath; // 线程安全集合存储所有场景执行结果 private final List<ScenarioMeta> scenarioResultList = Collections.synchronizedList(new ArrayList<>()); // 线程变量存储当前场景启动时间,避免并行测试数据串扰 private final ThreadLocal<Long> currentScenarioStartTime = new ThreadLocal<>(); // 构造方法传入Excel输出路径,和Cucumber插件传参规则适配 public CucumberExcelReportPlugin(String outputPath) { this.excelOutputPath = outputPath; } @Override public void setEventPublisher(EventPublisher publisher) { // 注册需要监听的Cucumber生命周期事件 publisher.registerHandlerFor(TestCaseStarted.class, this::handleTestCaseStart); publisher.registerHandlerFor(TestCaseFinished.class, this::handleTestCaseFinish); publisher.registerHandlerFor(TestStepFinished.class, this::handleTestStepFinish); } // 补全事件处理逻辑,所有事件收集完成后触发Excel写入方法 // Excel写入逻辑里实现表头创建、数据填充、样式设置 }
TestRunner类集成配置
自定义插件写完后,直接在TestRunner的@CucumberOptions注解的plugin参数里配置即可,和配置原生HTML、JSON报告的写法完全一致,不需要额外写执行触发逻辑,Cucumber会在所有用例执行完成后自动调用插件生成报告:
@RunWith(Cucumber.class) @CucumberOptions( features = "src/test/resources/features", glue = "com.xxx.test.steps", plugin = { "pretty", "html:target/report/cucumber-native.html", // 保留原生HTML报告做对照 "com.xxx.test.report.CucumberExcelReportPlugin:target/report/cucumber-excel-report.xlsx" }, monochrome = true ) public class CucumberTestRunner { // 类内不需要写任何额外执行代码 }
样式对齐原生报告的优化点
- 冻结Excel首行表头,和原生报告固定导航栏的交互逻辑一致
- 状态列做颜色标记:通过单元格背景色区分状态,PASSED填绿色、FAILED填红色、SKIPPED填黄色,和原生报告的状态色完全对应
- 失败信息列设置自动换行,调整列宽适配长文本,不需要手动拉伸单元格就能看全报错
- 报告顶部增加汇总统计行:展示总用例数、通过数、失败数、跳过数、总执行时长、通过率,和原生HTML报告首页的统计卡片信息对齐
- 支持同个Feature下的场景做分组展示,和原生报告按Feature折叠场景的层级结构一致
注意避坑
- 不要在步骤定义类的@Before/@After钩子中写Excel生成逻辑,这类写法不支持并行测试,容易出现数据串扰、文件写入冲突问题
- 失败栈信息不要全量写入Excel,只保留核心业务相关的3-5行栈信息即可,避免文件体积过大,和原生报告默认折叠冗余栈的逻辑一致
- 执行时长统计不要用钩子方法的时间计算,钩子执行时间不计入原生报告的场景耗时,用Cucumber生命周期事件统计的数值和原生报告完全匹配
内容的提问来源于stack exchange,提问作者Saeedanwar
相关产品推荐
相关产品推荐

