如何按Cucumber标签拆分TestNG测试,实现分标签多线程执行?
按Cucumber标签拆分并在不同线程执行的实现方案
针对你的需求(让@tag1的测试在一个线程顺序执行,@tag2的测试在另一个线程执行),结合TestNG 7.8和Cucumber 7.13,提供两种可行方案:
方案一:创建多个测试运行类(推荐)
这种方式直观易维护,每个标签对应独立的测试类,通过TestNG配置实现类级并行,每个类内部的场景自动顺序执行。
为每个标签创建专属测试类
分别编写对应@tag1和@tag2的测试运行类,在@CucumberOptions中指定目标标签,且不开启DataProvider并行(保证同标签场景顺序执行):@Log4j2 @CucumberOptions( features = "src/test/resources/features", glue = "com.epam.cucumber.step.definitions", tags = "@tag1", // 仅运行带@tag1的场景 plugin = {"pretty", "com.epam.core.rp.CustomScenarioReporter", "html:target/cucumber-reports/tag1-report.html", "json:target/cucumber-reports/tag1-report.json", "rerun:target/tag1-rerun.txt"}) public class RunTag1Tests extends AbstractTestNGCucumberTests { // 不重写scenarios方法,默认DataProvider parallel=false,场景顺序执行 }@Log4j2 @CucumberOptions( features = "src/test/resources/features", glue = "com.epam.cucumber.step.definitions", tags = "@tag2", // 仅运行带@tag2的场景 plugin = {"pretty", "com.epam.core.rp.CustomScenarioReporter", "html:target/cucumber-reports/tag2-report.html", "json:target/cucumber-reports/tag2-report.json", "rerun:target/tag2-rerun.txt"}) public class RunTag2Tests extends AbstractTestNGCucumberTests { // 不重写scenarios方法,默认DataProvider parallel=false,场景顺序执行 }配置TestNG并行执行测试类
通过TestNG XML配置文件开启类级并行:<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" > <suite name="Cucumber Parallel Suite" parallel="classes" thread-count="2"> <test name="Tag1 Tests"> <classes> <class name="com.epam.RunTag1Tests"/> </classes> </test> <test name="Tag2 Tests"> <classes> <class name="com.epam.RunTag2Tests"/> </classes> </test> </suite>
方案二:自定义DataProvider按标签分组(单类实现)
如果希望用同一个测试类实现,可以自定义DataProvider,将场景按标签分组,让TestNG为每组分配独立线程,组内场景顺序执行。
修改原测试类,重写scenarios方法:
@Log4j2 @CucumberOptions( features = "src/test/resources/features", glue = "com.epam.cucumber.step.definitions", plugin = {"pretty", "com.epam.core.rp.CustomScenarioReporter", "html:target/cucumber-reports/cucumber-report.html", "json:target/cucumber-reports/cucumber-report.json", "rerun:target/rerun.txt"}) public class RunTest extends AbstractTestNGCucumberTests { @Override @DataProvider(parallel = true) public Object[][] scenarios() { Object[][] allScenarios = super.scenarios(); List<Object[]> tag1Scenarios = new ArrayList<>(); List<Object[]> tag2Scenarios = new ArrayList<>(); // 遍历所有场景,按标签分组 for (Object[] scenario : allScenarios) { PickleWrapper pickleWrapper = (PickleWrapper) scenario[0]; Set<String> tags = pickleWrapper.getPickle().getTags().stream() .map(PickleTag::getName) .collect(Collectors.toSet()); if (tags.contains("@tag1")) { tag1Scenarios.add(scenario); } else if (tags.contains("@tag2")) { tag2Scenarios.add(scenario); } } // 将每组场景打包为数组元素,TestNG会为每个元素分配独立线程 return new Object[][]{ tag1Scenarios.toArray(new Object[0][]), tag2Scenarios.toArray(new Object[0][]) }; } }
关键说明
- 方案一逻辑清晰,各标签测试独立,便于单独运行某组测试,报告可分开生成,排查问题更高效。
- 方案二适合不想创建多类的场景,但需手动解析场景标签,代码复杂度稍高。
- 两种方案都能实现需求:@tag1的所有场景在一个线程顺序执行,@tag2的在另一个线程执行。
内容的提问来源于stack exchange,提问作者Katerina Zharskaya
相关产品推荐
相关产品推荐

