求助:Cucumber JUnit Selenide + Spring Boot并行测试无法运行
问题排查与解决方案
核心问题分析
你的并行测试未生效主要有以下几个原因:
- JUnit版本冲突与执行模型限制:使用JUnit 4的
@RunWith(Cucumber.class)时,所有Cucumber场景会被封装为单个JUnit测试方法,Surefire插件无法对单个场景进行并行拆分。同时项目中混合了JUnit 4和JUnit 5依赖,导致测试引擎执行逻辑混乱。 - Surefire插件配置不足:旧版本的Surefire插件(2.22.2)对JUnit 5和Cucumber原生并行支持有限,且未配置Cucumber专属的并行执行参数。
- Spring上下文缓存冲突:
@SpringBootTest默认缓存应用上下文,并行测试中多线程共享上下文会引发线程安全问题,同时也会阻碍并行执行的独立性。
具体修复步骤
1. 调整依赖配置
修改pom.xml中的依赖,移除JUnit 4相关的Cucumber依赖,切换到JUnit 5的Cucumber执行引擎:
<!-- 移除旧的JUnit 4 Cucumber依赖 --> <!-- <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit</artifactId> <version>${cucumber.version}</version> </dependency> --> <!-- 添加JUnit 5 Cucumber执行引擎 --> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit-platform-engine</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> <!-- 移除未使用的TestNG依赖(如果不使用TestNG) --> <!-- <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency> -->
2. 更新Surefire插件配置
升级插件版本并添加Cucumber并行执行参数:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M7</version> <!-- 升级到支持JUnit 5的新版本 --> <configuration> <parallel>methods</parallel> <!-- 按测试方法(即Cucumber场景)并行 --> <threadCount>3</threadCount> <properties> <configurationParameters> <!-- 启用Cucumber原生并行 --> cucumber.execution.parallel.enabled=true <!-- 固定线程数策略 --> cucumber.execution.parallel.config.strategy=fixed cucumber.execution.parallel.config.fixed.parallelism=3 <!-- 随机执行顺序避免依赖问题 --> cucumber.execution.order=random </configurationParameters> </properties> </configuration> </plugin> </plugins> </build>
3. 修改JUnit Runner类
切换到JUnit 5的Cucumber注解,移除JUnit 4的@RunWith,并修正Spring Boot Test的配置:
import io.cucumber.junit.platform.engine.Cucumber; import io.cucumber.spring.CucumberContextConfiguration; import org.springframework.boot.test.context.SpringBootTest; @Cucumber // 替换@RunWith(Cucumber.class) @CucumberContextConfiguration @SpringBootTest(classes = SpillenbodenApplication.class, // 移除测试类自身的引用 webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @CucumberOptions( features = {"classpath:features"}, glue = {"com.example.spillenboden.pageSteps"}, tags = "@login", plugin = {"pretty", "html:target/cucumber-reports/cucumber.html", "json:target/cucumber-reports/cucumber.json", "io.qameta.allure.cucumber6jvm.AllureCucumber6Jvm" }) public class SpillRegistrationRegressionTest { }
4. 解决Spring上下文冲突
在src/test/resources/application.properties中添加以下配置,禁用Spring测试上下文缓存:
# 禁用上下文缓存,确保每个并行线程获取独立上下文 spring.test.context.cache.maxSize=0
或者在测试类上添加@DirtiesContext注解:
import org.springframework.test.annotation.DirtiesContext; @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class SpillRegistrationRegressionTest { }
5. 验证Selenide配置
Selenide默认使用ThreadLocal管理WebDriver实例,确保每个线程拥有独立的浏览器实例,无需额外配置。但建议在每个场景结束后自动清理:
import com.codeborne.selenide.Selenide; import io.cucumber.java.After; public class Hooks { @After public void tearDown() { Selenide.closeWebDriver(); } }
验证并行执行
运行测试命令mvn test,观察控制台输出或浏览器实例,确认多个场景同时执行。可以通过查看Allure报告或Cucumber HTML报告中的执行时间,验证并行效果。
内容的提问来源于stack exchange,提问作者Salo
相关产品推荐
相关产品推荐

