如何阻止@CucumberContextConfiguration+@SpringBootTest在测试间重载应用上下文?
解决Cucumber Spring测试每次场景重启上下文的问题
针对你遇到的Cucumber-Spring 7.11.1版本中每个场景都重启Spring上下文导致测试变慢的问题,可以通过以下几个步骤解决:
1. 修正系统属性设置时机,避免重复触发上下文重建
你的FunctionalTestRunner中使用JUnit的@BeforeClass设置系统属性,这可能和Cucumber的生命周期冲突,导致属性重复设置或时机不当,触发上下文缓存失效。建议改用Cucumber原生的@BeforeAll钩子,确保属性只初始化一次:
package com.iggroup.ds.functional.stepdefinitions; import org.springframework.util.SocketUtils; import io.cucumber.java.BeforeAll; public class CucumberEnvironmentHooks { private static boolean environmentPrepared = false; @BeforeAll public static void prepareEnvironment() { if (!environmentPrepared) { int applicationPort = SocketUtils.findAvailableTcpPort(); System.setProperty("server.port", String.valueOf(applicationPort)); System.setProperty("spring.active.profiles", "FUNCTIONAL_TEST"); System.setProperty("spring.cloud.config.enabled", "false"); System.setProperty("spring.cloud.config.server.bootstrap", "false"); environmentPrepared = true; } } }
同时删除FunctionalTestRunner中的@BeforeClass方法,确保Cucumber完全控制初始化流程。
2. 调整WireMock配置,避免因WireMock重置触发上下文重启
默认的@AutoConfigureWireMock会在每次测试后重置映射并可能重启服务器,导致上下文刷新。可以关闭自动重置,改为手动在场景前重置WireMock:
修改Spring配置类:
@AutoConfigureWireMock(port = 8089, properties = { "wiremock.reset-mappings-after-each-test=false" }) @CucumberContextConfiguration @SpringBootTest( classes = {ServiceApplication.class, RestClients.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = { "spring.profiles.active=FUNCTIONAL_TEST", "spring.cloud.config.enabled=false" } ) public class FunctionalTestSpringCucumberConfiguration { }
在钩子类中添加场景前重置逻辑:
package com.iggroup.ds.functional.stepdefinitions; import com.github.tomakehurst.wiremock.WireMockServer; import io.cucumber.java.Before; import org.springframework.beans.factory.annotation.Autowired; public class CucumberWireMockHooks { @Autowired private WireMockServer wireMockServer; @Before public void resetWireMockStubs() { wireMockServer.resetAll(); // 重置stub,而非重启服务器 } }
3. 确保上下文缓存条件一致
Spring Test的上下文缓存基于配置的哈希值,任何配置差异都会触发上下文重建:
- 检查所有步骤定义类,确保没有使用
@MockBean、@SpyBean或@TestPropertySource等会改变上下文配置的注解 - 确认所有场景使用完全相同的
@SpringBootTest配置(包括classes、properties、webEnvironment参数)
4. 验证上下文缓存命中情况
添加日志配置验证缓存是否生效,在application-FUNCTIONAL_TEST.properties中加入:
logging.level.org.springframework.test.context.cache=DEBUG
运行测试时,若看到Context cache hit日志,说明上下文已被复用;若频繁出现Creating new context,则需要排查是否仍有配置差异。
内容的提问来源于stack exchange,提问作者Carlton Sandhu
相关产品推荐
相关产品推荐

