How to stop @CucumberContextConfiguration with @SpringBootTest from reloading application context between every test?

huangapple go评论90阅读模式
英文:

How to stop @CucumberContextConfiguration with @SpringBootTest from reloading application context between every test?

问题

我遇到了一个问题,我的应用程序上下文在每次测试之间重新加载。我正在使用功能测试属性、wiremock等将我的实际应用程序与功能测试环境进行连接。测试一直都运行得很好,但现在我们添加了几个测试,由于每次重新运行Spring应用程序,测试变得非常慢。我在我的pom中使用的io.cucumber版本为cucumber-spring、cucumber-java、cucumber-junit的7.11.1版本。

我的功能测试运行器被注解如下:

  1. @RunWith(Cucumber.class)
  2. @CucumberOptions(
  3. features = "classpath:functional/features",
  4. glue = {"com.iggroup.ds.functional.stepdefinitions"},
  5. monochrome = true,
  6. tags = "@FunctionalTest",
  7. plugin = {"pretty", "html:target/cucumber-html-report", "junit:target/cucumber-xml-report.xml"}
  8. )
  9. public class FunctionalTestRunner {
  10. @BeforeClass
  11. public static void beforeClass() {
  12. prepareEnvironment();
  13. }
  14. private static void prepareEnvironment() {
  15. int applicationPort = SocketUtils.findAvailableTcpPort();
  16. System.setProperty("server.port", String.valueOf(applicationPort));
  17. System.setProperty("spring.active.profiles", "FUNCTIONAL_TEST");
  18. System.setProperty("spring.cloud.config.enabled", "false");
  19. System.setProperty("spring.cloud.config.server.bootstrap", "false");
  20. }
  21. }

在我的glue包内,Cucumber配置如下:

  1. @AutoConfigureWireMock(port = 8089)
  2. @CucumberContextConfiguration
  3. @SpringBootTest(
  4. classes = {
  5. ServiceApplication.class,
  6. RestClients.class
  7. },
  8. webEnvironment = DEFINED_PORT,
  9. properties = {
  10. "spring.profiles.active=FUNCTIONAL_TEST",
  11. "spring.cloud.config.enabled=false"
  12. }
  13. )
  14. public class FunctionalTestSpringCucumberConfiguration {
  15. }

最后,应用程序本身如下:

  1. @EnableAsync
  2. @EnableCaching
  3. @EnableConfigServer
  4. @SpringBootApplication
  5. @EnableConfigurationProperties
  6. public class ServiceApplication extends SpringBootServletInitializer {
  7. public static void main(String[] args) {
  8. SpringApplication.run(ServiceApplication.class, args);
  9. }
  10. }

我之前在某个地方看到过,@MockBean的存在会导致上下文之间的意外刷新,尽管我从未找出为什么会这样,但我并没有定义任何@MockBean。据我所知,在我阅读的文章中,这不应该在每个场景之间刷新我的上下文,所以想知道是否有任何方法可以强制它不在每个场景之间重新连接ServiceApplication.class?

英文:

I've got this problem where my application context is reloaded between every test. I'm wiring in my actual application with functional test properties, wiremock etc. to create a functional test environment. Tests have always run fine but now we've added several it's become painfully slow due to the spring application being re-run everytime. The io.cucumber versions I'm using in my pom for cucumber-spring, cucumber-java, cucumber-junit is 7.11.1.
My Functional Test runner is annotated like this:

  1. @RunWith(Cucumber.class)
  2. @CucumberOptions(
  3. features = "classpath:functional/features",
  4. glue = {"com.iggroup.ds.functional.stepdefinitions"},
  5. monochrome = true,
  6. tags = "@FunctionalTest",
  7. plugin = {"pretty", "html:target/cucumber-html-report", "junit:target/cucumber-xml-report.xml"}
  8. )
  9. public class FunctionalTestRunner {
  10. @BeforeClass
  11. public static void beforeClass() {
  12. prepareEnvironment();
  13. }
  14. private static void prepareEnvironment() {
  15. int applicationPort = SocketUtils.findAvailableTcpPort();
  16. System.setProperty("server.port", String.valueOf(applicationPort));
  17. System.setProperty("spring.active.profiles", "FUNCTIONAL_TEST");
  18. System.setProperty("spring.cloud.config.enabled", "false");
  19. System.setProperty("spring.cloud.config.server.bootstrap", "false");
  20. }
  21. }

Inside my glue package the Cucumber Configuration looks like this:

  1. @AutoConfigureWireMock(port = 8089)
  2. @CucumberContextConfiguration
  3. @SpringBootTest(
  4. classes = {
  5. ServiceApplication.class,
  6. RestClients.class
  7. },
  8. webEnvironment = DEFINED_PORT,
  9. properties = {
  10. "spring.profiles.active=FUNCTIONAL_TEST",
  11. "spring.cloud.config.enabled = false"
  12. }
  13. )
  14. public class FunctionalTestSpringCucumberConfiguration {
  15. }

And lastly the application itself looks like this:

  1. @EnableAsync
  2. @EnableCaching
  3. @EnableConfigServer
  4. @SpringBootApplication
  5. @EnableConfigurationProperties
  6. public class ServiceApplication extends SpringBootServletInitializer {
  7. public static void main(String[] args) {
  8. SpringApplication.run(ServiceApplication.class, args);
  9. }
  10. }

I had read somewhere before that the presence of @MockBean was causing unexpected refreshes between context although I never found out as to why - but I have none defined. As far as I can tell across the articles I've been reading, this shouldn't refresh my context every time so wondering if there's any way I can force it not to rewire the ServiceApplication.class in between every scenario?

答案1

得分: 0

  1. @AutoConfigureWireMock(port = 8089)

通过在固定端口上使用WireMock,你会使应用程序上下文变脏。这意味着每个测试将会创建一个新的应用程序上下文。负责此操作的代码会在日志中打印一个警告信息。

  1. if (portIsFixed(testContext)) {
  2. if (log.isWarnEnabled()) {
  3. log.warn("您已经使用了固定端口进行WireMock设置 - 将会标记上下文为脏。请尽量使用随机端口,这样您的测试将会更快、更可靠,此警告将会消失");
  4. }
  5. testContext.markApplicationContextDirty(DirtiesContext.HierarchyMode.EXHAUSTIVE);
  6. }
英文:
  1. @AutoConfigureWireMock(port = 8089)

By using Wiremock on fixed port you are dirtying the application context. This means a new application context will be created for each test. The code responsible for this prints a warning that you can see in your logs.

  1. if (portIsFixed(testContext)) {
  2. if (log.isWarnEnabled()) {
  3. log.warn("You've used fixed ports for WireMock setup - "
  4. + "will mark context as dirty. Please use random ports, as much "
  5. + "as possible. Your tests will be faster and more reliable and this "
  6. + "warning will go away");
  7. }
  8. testContext.markApplicationContextDirty(DirtiesContext.HierarchyMode.EXHAUSTIVE);
  9. }

huangapple
  • 本文由 发表于 2023年2月6日 19:02:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75360474.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定