Cucumber集成Spring Boot测试报No test instance异常排查
问题根因
- 核心触发原因是
@CucumberContextConfiguration注解被直接标注在了步骤定义类DwhStepDef上,而该类同时实现了cucumber-java8提供的En接口,通过构造函数内lambda的形式定义测试步骤,触发了cucumber-spring 7.4.1版本的实例绑定缺陷:- Cucumber在执行场景前会独立完成Spring测试上下文初始化、步骤类实例化两个流程,当配置注解和步骤定义写在同一个类时,两个流程的实例传递逻辑断裂,Spring TestContext管理器中持有的
testInstance属性始终为null - 由于上下文初始化、步骤执行阶段不需要从Spring TestContext中获取测试实例(Cucumber自身持有步骤类的实例引用),因此会出现你观察到的现象:Spring上下文正常启动、feature文件正常识别、步骤正常执行,只有场景执行完成进入清理阶段时,
TestContextAdaptor调用afterTestMethod生命周期回调需要获取测试实例,才会抛出No test instance异常
- Cucumber在执行场景前会独立完成Spring测试上下文初始化、步骤类实例化两个流程,当配置注解和步骤定义写在同一个类时,两个流程的实例传递逻辑断裂,Spring TestContext管理器中持有的
- 你当前配置中
@SpringBootTest和@ContextConfiguration同时指定DwhE2EApplication.class属于冗余配置,不会直接触发异常,但建议清理避免潜在配置冲突。
修复方案
按照以下步骤调整即可解决问题:
- 新建独立的Cucumber Spring配置类,专门存放测试上下文相关注解,这个类必须为空,不要写任何步骤定义逻辑,也不要实现
En接口:
import io.cucumber.spring.CucumberContextConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @SpringBootTest(classes = DwhE2EApplication.class, webEnvironment = RANDOM_PORT) @CucumberContextConfiguration @ActiveProfiles("test") public class CucumberSpringConfiguration { // 无需编写任何代码 }
- 清理原
DwhStepDef类上的Spring测试相关注解,只保留步骤定义逻辑:
public class DwhStepDef implements En { // 原有Given/When/Then步骤逻辑、依赖注入代码保持不变 public DwhStepDef() { // 原有lambda形式的步骤定义不需要修改 } }
- (可选兜底方案)如果完成上述修改后仍存在异常,可以将Cucumber版本升级到7.14.0及以上,新版本已经修复了cucumber-spring模块多个实例绑定、生命周期回调相关的已知缺陷,升级仅需修改Gradle依赖中的BOM版本号,不需要调整业务代码:
testImplementation(platform("io.cucumber:cucumber-bom:7.14.0"))
验证标准
调整完成后重新执行测试:
- Spring上下文正常加载,测试步骤正常执行
- 场景执行完成后的资源清理阶段不再抛出
No test instance异常 - 步骤类中注入的Spring Bean(比如Service、Repository、测试组件等)可以正常使用
内容的提问来源于stack exchange,提问作者Vincent F
相关产品推荐
相关产品推荐

