如何在可执行测试JAR中运行Cucumber+SpringBootTest
解决Cucumber + SpringBootTest可执行JAR运行时Spring上下文未初始化问题
核心问题分析
打包后运行报错提示MyStepDefs类无公共无参构造,本质是Cucumber未触发Spring上下文初始化:IDE中运行时Spring Boot的测试框架会自动加载上下文并管理Bean,但maven-assembly-plugin打包的JAR未正确处理Spring的类路径、依赖加载逻辑,导致Cucumber无法通过Spring获取StepDefs实例,只能尝试用无参构造创建,最终失败。
方案1:改用Spring Boot官方Maven插件打包(推荐)
Spring Boot的spring-boot-maven-plugin专门适配可执行JAR打包,能自动处理上下文初始化、依赖打包等问题。
- 替换pom.xml中的
maven-assembly-plugin为以下配置:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>你的Spring Boot对应版本</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <!-- 指定测试主类路径 --> <mainClass>example.cucumberspringexecutabletests.MainTest</mainClass> <!-- 生成带tests后缀的可执行JAR,区分业务JAR --> <classifier>tests</classifier> </configuration> </plugin> </plugins> </build>
- 执行打包命令:
mvn clean package
- 运行生成的JAR:
java -jar target/项目名-tests.jar
方案2:适配maven-assembly-plugin的配置(需手动处理上下文)
如果坚持使用maven-assembly-plugin,需强制Cucumber加载Spring上下文并正确打包依赖:
步骤1:添加Cucumber-Spring上下文配置类
创建专门的配置类,告诉Cucumber要使用Spring上下文:
package example.cucumberspringexecutabletests.config; import org.springframework.boot.test.context.SpringBootTest; import io.cucumber.spring.CucumberContextConfiguration; @CucumberContextConfiguration @SpringBootTest public class CucumberSpringConfig { // 无需额外代码,仅作为Spring上下文的标记类 }
步骤2:调整maven-assembly-plugin配置
确保测试类、资源、所有依赖都被打包:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <mainClass>example.cucumberspringexecutabletests.MainTest</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- 包含测试类、StepDefs、feature文件 --> <includes> <include>**/test-classes/**</include> <include>**/steps/**</include> <include>**/*.feature</include> </includes> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
步骤3:修改主类的Cucumber启动参数
在MainTest中明确指定Spring配置类的路径,强制Cucumber加载上下文:
import io.cucumber.core.cli.Main; public class MainTest { public static void main(String[] args) { String[] cucumberArgs = { "--glue", "example.cucumberspringexecutabletests", "--glue", "example.cucumberspringexecutabletests.config", // 指向上面的配置类 "classpath:features" }; Main.run(cucumberArgs, Thread.currentThread().getContextClassLoader()); } }
通用注意事项
- 所有StepDefs类必须添加
@Component注解,让Spring管理实例:
import org.springframework.stereotype.Component; @Component public class MyStepDefs { private final MyService myService; // 保留有参构造,由Spring注入依赖 public MyStepDefs(MyService myService) { this.myService = myService; } // 步骤定义代码... }
- 不要给StepDefs添加无参构造,否则会优先被Cucumber使用,跳过Spring依赖注入。
内容的提问来源于stack exchange,提问作者Aditya Abinash
相关产品推荐
相关产品推荐

