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

如何在基于io.cucumber.core.cli.Main的Gradle任务中指定Cucumber执行时的EventListener?

解决Gradle中Cucumber CLI执行时指定TestNG EventListener的问题

你的核心问题在于:Cucumber CLI执行模式和TestNG Runner模式是完全独立的执行路径——TestNG的@Listeners注解是TestNG框架识别的,而Cucumber CLI直接启动Cucumber核心,不会触发TestNG的生命周期,所以原来的EventListener(TestNG的IListener实现)在CLI模式下根本不会被调用。

下面给你两种可行的解决方案,优先推荐第一种,因为不需要修改现有监听器代码:


方案1:保留TestNG执行流程,动态传递Tags(推荐)

这个方案不用切换到Cucumber CLI,而是通过修改TestNG Runner和Gradle任务,实现动态传递Tags参数,同时保留TestNG监听器的功能。

步骤1:修改TestNGRunner.java,支持读取系统属性的Tags

把硬编码的tags = "@Regression"改成读取系统属性,同时设置默认值:

package runners;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.Listeners;
import rs.ananas.automation.utils.listeners.EventListener;

@CucumberOptions(
 features = "src/test/resources/features/",
 glue = { "rs.ananas.automation.common", "rs.ananas.automation.steps" },
 tags = "${cucumber.tags:@Regression}", // 从系统属性读取,默认@Regression
 plugin = {"pretty", "html:src/test/resources/reports/cucumber-report.html", "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:", "rs.ananas.automation.utils.listeners.StepEventListener" }
)
@Listeners(EventListener.class) // 这个监听器会正常生效
public class TestNGRunner extends AbstractTestNGCucumberTests {
}

步骤2:修改Gradle任务,传递系统属性并使用TestNG执行

替换原来的cucumber任务为一个TestNG类型的任务,直接运行你的TestNGRunner:

task runCucumberWithTags(type: Test) {
    dependsOn assemble, compileTestJava
    useTestNG() {
        // 可以指定TestNG套件xml,或者直接指定Runner类
        suites 'src/test/testng.xml'
        // 传递CLI传入的tags系统属性给TestNG
        systemProperty 'cucumber.tags', System.getProperty('cucumber.tags', '@Regression')
    }
    classpath = sourceSets.test.runtimeClasspath
}

使用方式

现在你可以通过CLI动态指定Tags,同时EventListener会正常工作:

gradle clean runCucumberWithTags -Dcucumber.tags="@Smoke"

方案2:将TestNG监听器转为Cucumber插件(适合坚持用CLI的场景)

如果你一定要用Cucumber CLI执行,需要把原来的TestNG EventListener改造成Cucumber原生的插件(实现Cucumber的EventListener接口),因为Cucumber CLI只识别自己的插件体系。

步骤1:创建Cucumber版本的EventListener

把原来的TestNG监听器逻辑迁移到Cucumber的事件监听接口:

package rs.ananas.automation.utils.listeners;

import io.cucumber.plugin.EventListener;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.TestCaseStarted;
import io.cucumber.plugin.event.TestCaseFinished;
import io.cucumber.plugin.event.TestCaseSkipped;
import io.cucumber.plugin.event.Result;

public class CucumberEventListener implements EventListener {

    @Override
    public void setEventPublisher(EventPublisher publisher) {
        // 注册需要监听的Cucumber事件
        publisher.registerHandlerFor(TestCaseStarted.class, this::onTestCaseStarted);
        publisher.registerHandlerFor(TestCaseFinished.class, this::onTestCaseFinished);
        publisher.registerHandlerFor(TestCaseSkipped.class, this::onTestCaseSkipped);
        // 可以根据需要添加更多事件,比如TestStepStarted、TestStepFinished等
    }

    private void onTestCaseStarted(TestCaseStarted event) {
        // 迁移原来onTestStart的逻辑,适配Cucumber的事件对象
        String testCaseName = event.getTestCase().getName();
        // 你的数据库记录逻辑...
    }

    private void onTestCaseFinished(TestCaseFinished event) {
        // 迁移原来onTestFinished的逻辑
        Result result = event.getResult();
        switch (result.getStatus()) {
            case PASSED:
                // 处理通过的用例
                break;
            case FAILED:
                // 处理失败的用例
                break;
            // 其他状态...
        }
        // 数据库插入逻辑...
    }

    private void onTestCaseSkipped(TestCaseSkipped event) {
        // 迁移原来onTestSkipped的逻辑
    }
}

步骤2:修改Gradle的cucumber任务,添加Cucumber插件

在javaexec的args里新增你的Cucumber插件:

task cucumber(type: Test) {
    dependsOn assemble, compileTestJava
    doLast {
        javaexec {
            main = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
            args = [
                '-g', 'rs.ananas.automation.common',
                '-g', 'rs.ananas.automation.steps',
                '-t', System.getProperty("cucumber.tags", "@Regression"), // 增加默认值避免空指针
                '-p', 'com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:',
                '-p', 'rs.ananas.automation.utils.listeners.StepEventListener',
                '-p', 'rs.ananas.automation.utils.listeners.CucumberEventListener' // 新增这个Cucumber插件
            ]
        }
    }
}

使用方式

运行方式和你原来的一样:

gradle clean cucumber -Dcucumber.tags="@Regression"

方案对比

  • 方案1:无需修改现有监听器代码,完全保留TestNG的生态(包括EventListener的数据库记录逻辑),适合你的Jenkins CI流程,是最省心的选择。
  • 方案2:需要改造监听器代码,但可以使用Cucumber原生CLI的特性,适合对Cucumber原生执行有需求的场景。

内容的提问来源于stack exchange,提问作者Bogdan Jovanovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 12:19:14