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

如何基于选定环境程序化配置Cucumber标签与Feature文件执行?

基于环境动态指定Cucumber标签与Feature文件的优化方案

你之前用@Before抛SkipException的方式会导致被跳过的场景出现在测试报告中,且属于运行时过滤,效率较低。更优的做法是在测试用例生成阶段就过滤掉不需要的场景/Feature,完全避免生成无关测试用例,报告中也不会出现跳过条目。以下是几种适配Spring Boot+Cucumber+TestNG的简洁实现方式:

方案1:系统属性+Spring环境变量(推荐,最简单)

Cucumber支持通过系统属性直接覆盖@CucumberOptions的配置,结合Spring的环境变量读取能力,可轻松实现环境驱动的动态配置:

1.1 修改测试运行器

保留基础配置,通过系统属性动态覆盖标签和Feature路径:

@SpringBootTest(classes = YourApplication.class)
@CucumberOptions(
    features = {"src/test/resources/Features"}, // 默认路径
    glue = {"als.system.tests.stepDefinations"},
    plugin = {"pretty", "html:target/cucumber-html-report.html"}
)
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {

    @Value("${test.env:dev}") // 从Spring环境读取,默认dev
    private String targetEnv;

    @BeforeClass
    public void setupCucumberProps() {
        // 动态设置标签过滤规则
        System.setProperty("cucumber.filter.tags", "@" + targetEnv.toLowerCase());
        // 动态指定Feature目录(按环境分目录存放时使用)
        System.setProperty("cucumber.features", "src/test/resources/Features/" + targetEnv);
    }
}

1.2 启动测试时指定环境

通过JVM参数或Spring配置文件指定目标环境:

# Maven启动时指定prod环境
mvn test -Dtest.env=prod

# Gradle启动时指定prod环境
./gradlew test -Dtest.env=prod

也可在src/test/resources/application-test.properties中配置默认环境:

test.env=dev

方案2:重写TestNG DataProvider(自定义过滤逻辑)

如果需要更复杂的过滤规则(比如多标签组合、Feature路径匹配),可重写AbstractTestNGCucumberTests的scenarios() DataProvider,直接过滤掉不需要的场景:

@SpringBootTest(classes = YourApplication.class)
@CucumberOptions(
    features = {"src/test/resources/Features"},
    glue = {"als.system.tests.stepDefinations"},
    plugin = {"pretty", "html:target/cucumber-html-report.html"}
)
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {

    @Value("${test.env:dev}")
    private String targetEnv;

    @Override
    @DataProvider(parallel = true)
    public Object[][] scenarios() {
        // 获取所有原始场景
        Object[][] allScenarios = super.scenarios();
        
        // 过滤出符合目标环境标签的场景
        return Arrays.stream(allScenarios)
                .filter(scenario -> {
                    PickleWrapper pickle = (PickleWrapper) scenario[0];
                    // 提取场景所有标签
                    Set<String> tags = pickle.getPickle().getTags().stream()
                            .map(PickleTag::getName)
                            .collect(Collectors.toSet());
                    // 匹配目标环境标签,可扩展多标签逻辑
                    return tags.contains("@" + targetEnv.toLowerCase());
                })
                .toArray(Object[][]::new);
    }
}

此方案完全自定义过滤逻辑,过滤后的场景才会生成测试用例,报告中仅显示实际执行的内容。

方案3:Cucumber编程式API(高级自定义)

若需要极致灵活的配置(比如动态加载Feature路径、多环境组合),可直接使用Cucumber的TestNG编程式API:

import io.cucumber.testng.CucumberOptions;
import io.cucumber.testng.CucumberOptionsBuilder;
import io.cucumber.testng.FeatureWrapper;
import io.cucumber.testng.PickleWrapper;
import io.cucumber.testng.TestNGCucumberRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

@SpringBootTest(classes = YourApplication.class)
public class CucumberRunnerTests {

    @Value("${test.env:dev}")
    private String targetEnv;

    private TestNGCucumberRunner testRunner;

    @BeforeClass(alwaysRun = true)
    public void setUp() {
        // 动态构建Cucumber配置
        CucumberOptions options = new CucumberOptionsBuilder()
                .features("src/test/resources/Features/" + targetEnv)
                .glue("als.system.tests.stepDefinations")
                .tags("@" + targetEnv)
                .plugin("pretty", "html:target/cucumber-html-report.html")
                .build();
        testRunner = new TestNGCucumberRunner(this.getClass(), options);
    }

    @Test(groups = "cucumber", dataProvider = "scenarios")
    public void runScenario(PickleWrapper pickle, FeatureWrapper feature) {
        testRunner.runScenario(pickle.getPickle());
    }

    @DataProvider(parallel = true)
    public Object[][] scenarios() {
        return testRunner.provideScenarios();
    }

    @AfterClass(alwaysRun = true)
    public void tearDown() {
        testRunner.finish();
    }
}

此方案完全脱离注解配置,所有参数均可程序化生成,适合复杂的多环境测试场景。

内容的提问来源于stack exchange,提问作者Harshit Soni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:20:31