You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 19:09:22