JUnit5+Cucumber+Gradle命令行测试报UnknownClass.Cucumber初始化错误
问题描述
团队从JUnit4迁移至JUnit5后,Cucumber并行测试无法正常运行。原JUnit4中通过-Dcucumber.options="--threads 5"实现多线程的参数已被弃用,参考文档配置JUnit Platform Engine后,通过Gradle命令行运行测试时出现以下错误:
UnknownClass.Cucumber > UnknownClass.initializationError FAILED
org.junit.platform.commons.JUnitException at EngineExecutionOrchestrator.java:114
Caused by: org.junit.platform.commons.JUnitException at HierarchicalTestEngine.java:57
Caused by: org.junit.platform.commons.JUnitException at DefaultParallelExecutionConfigurationStrategy.java:41
技术栈
- Spring Boot 2.7.3
- Gradle 7.5.1
- Cucumber java、junit、spring、junit-platform-engine 5.7.0
- junit-platform-suite-api 1.3.2
当前配置
build.gradle 配置
useJUnitPlatform() systemProperty("cucumber.junit-platform.naming-strategy", "long") systemProperty("cucumber.execution.parallel.enabled", true) systemProperty("cucumber.execution.parallel.config.strategy", "fixed") systemProperty("cucumber.plugin", "html:reports/html") systemProperty("cucumber.plugin", "pretty") systemProperty("cucumber.plugin", "junit:reports/junit") doLast { javaexec { mainClass.set("io.cucumber.core.cli.Main") classpath = cucumberRuntime + sourceSets.test.get().output + sourceSets.main.get().output } } } tasks { val consoleLauncherTest by registering(JavaExec::class) { dependsOn(testClasses) val reportsDir = file("$buildDir/test-results") outputs.dir(reportsDir) classpath = sourceSets["test"].runtimeClasspath mainClass.set("org.junit.platform.console.ConsoleLauncher") args("--scan-classpath") args("--include-engine", "cucumber") args("--reports-dir", reportsDir) } test { dependsOn(consoleLauncherTest) exclude("**/*") } }
Cucumber配置类
@CucumberContextConfiguration @Suite @IncludeEngines("cucumber") @SelectClasspathResource("com/example") @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example") @SpringBootTest @ContextConfiguration(classes = [IntegrationContext::class], loader = SpringBootContextLoader::class) class Application() {}
问题原因分析
- 并行配置不完整:仅开启并行并设置策略为
fixed,但未指定具体线程数,导致Cucumber无法初始化并行配置,触发DefaultParallelExecutionConfigurationStrategy异常。 - 依赖版本不兼容:Cucumber 5.7.0需匹配JUnit Platform 1.7.x版本,当前使用的junit-platform-suite-api 1.3.2版本过低,引发初始化冲突。
- Gradle任务配置冗余:自定义
consoleLauncherTest任务未传递Cucumber系统属性,且test任务依赖该任务并排除所有测试,导致并行配置未生效。 - 重复配置覆盖:
cucumber.plugin被多次设置,Gradle会覆盖前面的配置,仅保留最后一项,可能间接引发初始化问题。
解决方案
1. 补全并行配置参数
添加固定线程数配置,对应原JUnit4的--threads 5:
systemProperty("cucumber.execution.parallel.config.fixed.parallelism", "5")
2. 对齐依赖版本
将junit-platform-suite-api及对应engine版本升级至1.7.2(与Cucumber 5.7.0匹配):
testImplementation("org.junit.platform:junit-platform-suite-api:1.7.2") testRuntimeOnly("org.junit.platform:junit-platform-suite-engine:1.7.2")
3. 简化Gradle任务配置
删除冗余的consoleLauncherTest任务,直接使用标准test任务运行,合并重复的plugin配置:
test { useJUnitPlatform() // Cucumber核心配置 systemProperty("cucumber.junit-platform.naming-strategy", "long") systemProperty("cucumber.execution.parallel.enabled", true) systemProperty("cucumber.execution.parallel.config.strategy", "fixed") systemProperty("cucumber.execution.parallel.config.fixed.parallelism", "5") // 合并插件配置,用逗号分隔多个输出 systemProperty("cucumber.plugin", "html:reports/html,pretty,junit:reports/junit") // 指定扫描Cucumber测试类 include("**/*CucumberTests.class") }
同时删除原doLast中的javaexec调用,useJUnitPlatform()已足够运行Cucumber测试。
4. 拆分配置类与测试启动类
将Cucumber Spring配置与测试启动类拆分,避免注解冲突:
Cucumber Spring配置类
@CucumberContextConfiguration @SpringBootTest(classes = [IntegrationContext::class]) class CucumberSpringConfiguration {}
Cucumber测试启动类
@Suite @IncludeEngines("cucumber") @SelectClasspathResource("com/example") @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example") class CucumberTestSuite {}
5. 验证运行
执行Gradle命令启动测试:
./gradlew test
内容的提问来源于stack exchange,提问作者molchu_tv

