SpringBoot+SerenityBDD+Cucumber测试无法加载application.properties问题
SpringBoot + SerenityBDD + Cucumber 配置加载NPE问题排查与解决
一、两类@RunWith的核心差异
@RunWith(SpringRunner.class):是Spring官方为JUnit提供的扩展Runner,启动时会完整初始化Spring应用上下文,自动处理组件扫描、依赖注入、配置属性绑定等所有Spring核心机制,所以你的单元测试能正常获取到配置值。- Serenity/Cucumber相关Runner(如
@RunWith(CucumberWithSerenity.class)):默认核心职责是驱动Cucumber场景执行、收集测试数据生成Serenity报告,不会自动启动Spring上下文,因此Spring的依赖注入逻辑完全不生效,导致BaseTest里的ServerConfig实例为null,调用方法时抛出NPE。
二、问题解决方法
1. 引入必要的整合依赖
确保pom.xml中包含Serenity与Spring、Cucumber与Spring的整合包,让两者能联动:
<!-- Serenity Spring整合 --> <dependency> <groupId>net.serenity-bdd</groupId> <artifactId>serenity-spring</artifactId> <version>${serenity.version}</version> <scope>test</scope> </dependency> <!-- Cucumber Spring整合 --> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-spring</artifactId> <version>${cucumber.version}</version> <scope>test</scope> </dependency>
2. 配置Cucumber测试入口类,启动Spring上下文
在你的Cucumber测试启动类上添加SpringBoot相关注解,让Serenity在启动测试时同时初始化Spring上下文:
@RunWith(CucumberWithSerenity.class) @CucumberOptions( features = "src/test/resources/features", // 你的feature文件路径 glue = "com.yourpackage.stepdefs" // 步骤定义类所在包 ) @CucumberContextConfiguration // 告诉Cucumber用这个类的配置初始化上下文 @SpringBootTest(classes = YourSpringBootApplication.class) // 指定SpringBoot启动类 public class RunCucumberTests { }
3. 确保Spring能管理相关组件
- 给
ServerConfig类添加@ConfigurationProperties(prefix = "url")和@Component(或者在SpringBoot启动类上添加@EnableConfigurationProperties(ServerConfig.class)),让Spring能扫描并绑定配置:@Component @ConfigurationProperties(prefix = "url") public class ServerConfig { private String lcs; // getter、setter } - 如果要保留
BaseTest的复用逻辑,给BaseTest添加@TestComponent(或@Component),让Spring能扫描到它,这样注入到MyStepdefs的BaseTest才是Spring管理的实例,内部的ServerConfig才会被正确注入:@TestComponent public class BaseTest { @Autowired private ServerConfig serverConfig; public void printServerConfig() { System.out.println(serverConfig.getLcs()); } }
4. 调整步骤定义类的注入方式
步骤定义类直接通过Spring注入BaseTest(或直接注入ServerConfig),不需要手动实例化:
public class MyStepdefs { @Autowired private BaseTest baseTest; @Given("some step") public void someStep() { baseTest.printServerConfig(); // 此时不会再抛出NPE } }
三、注意事项
- 不要在Serenity+Cucumber测试中混用
SpringRunner.class,必须用CucumberWithSerenity.class作为Runner,Spring上下文的初始化通过@SpringBootTest和@CucumberContextConfiguration触发。 - 检查所有需要Spring管理的类的包路径,确保在SpringBoot的组件扫描范围内(默认是启动类所在包及其子包)。
内容的提问来源于stack exchange,提问作者Abrar Ahamed
相关产品推荐
相关产品推荐

