You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:32:28