英文:
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版本。
我的功能测试运行器被注解如下:
@RunWith(Cucumber.class)
@CucumberOptions(
features = "classpath:functional/features",
glue = {"com.iggroup.ds.functional.stepdefinitions"},
monochrome = true,
tags = "@FunctionalTest",
plugin = {"pretty", "html:target/cucumber-html-report", "junit:target/cucumber-xml-report.xml"}
)
public class FunctionalTestRunner {
@BeforeClass
public static void beforeClass() {
prepareEnvironment();
}
private static void prepareEnvironment() {
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");
}
}
在我的glue包内,Cucumber配置如下:
@AutoConfigureWireMock(port = 8089)
@CucumberContextConfiguration
@SpringBootTest(
classes = {
ServiceApplication.class,
RestClients.class
},
webEnvironment = DEFINED_PORT,
properties = {
"spring.profiles.active=FUNCTIONAL_TEST",
"spring.cloud.config.enabled=false"
}
)
public class FunctionalTestSpringCucumberConfiguration {
}
最后,应用程序本身如下:
@EnableAsync
@EnableCaching
@EnableConfigServer
@SpringBootApplication
@EnableConfigurationProperties
public class ServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
我之前在某个地方看到过,@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:
@RunWith(Cucumber.class)
@CucumberOptions(
features = "classpath:functional/features",
glue = {"com.iggroup.ds.functional.stepdefinitions"},
monochrome = true,
tags = "@FunctionalTest",
plugin = {"pretty", "html:target/cucumber-html-report", "junit:target/cucumber-xml-report.xml"}
)
public class FunctionalTestRunner {
@BeforeClass
public static void beforeClass() {
prepareEnvironment();
}
private static void prepareEnvironment() {
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");
}
}
Inside my glue package the Cucumber Configuration looks like this:
@AutoConfigureWireMock(port = 8089)
@CucumberContextConfiguration
@SpringBootTest(
classes = {
ServiceApplication.class,
RestClients.class
},
webEnvironment = DEFINED_PORT,
properties = {
"spring.profiles.active=FUNCTIONAL_TEST",
"spring.cloud.config.enabled = false"
}
)
public class FunctionalTestSpringCucumberConfiguration {
}
And lastly the application itself looks like this:
@EnableAsync
@EnableCaching
@EnableConfigServer
@SpringBootApplication
@EnableConfigurationProperties
public class ServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
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
@AutoConfigureWireMock(port = 8089)
通过在固定端口上使用WireMock,你会使应用程序上下文变脏。这意味着每个测试将会创建一个新的应用程序上下文。负责此操作的代码会在日志中打印一个警告信息。
if (portIsFixed(testContext)) {
if (log.isWarnEnabled()) {
log.warn("您已经使用了固定端口进行WireMock设置 - 将会标记上下文为脏。请尽量使用随机端口,这样您的测试将会更快、更可靠,此警告将会消失");
}
testContext.markApplicationContextDirty(DirtiesContext.HierarchyMode.EXHAUSTIVE);
}
英文:
@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.
if (portIsFixed(testContext)) {
if (log.isWarnEnabled()) {
log.warn("You've used fixed ports for WireMock setup - "
+ "will mark context as dirty. Please use random ports, as much "
+ "as possible. Your tests will be faster and more reliable and this "
+ "warning will go away");
}
testContext.markApplicationContextDirty(DirtiesContext.HierarchyMode.EXHAUSTIVE);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论