我有一个典型的Gradle多项目构建:
project(':common') {
}
project(':project-a') {
dependencies {
compile project(':common')
..
}
}
...
project(':project-n') {
dependencies {
compile project(':common')
..
}
}
project(':app') {
dependencies {
compile project(':project-a')
..
compile project(':project-n')
..
}
}
所有子项目都有一个共同的任务,即integrataionTest
,它运行所有集成测试套件(类)。这些类继承自使用典型弹簧测试内容注释的公共父级:
@ContextConfiguration // needed until Spock supports @SpringBootTest
@SpringBootTest(classes = IntegrationTestConfiguration)
@ActiveProfiles("test")
class BaseTest extends Specification {
IntegrationTestConfiguration
是使用@Configuration
注释的@EnableAutoConfiguration
类,并且只预定义了实际完整@SpringBootApplication
类之外的其他bean。
问题是调用gradle integrationTest
似乎开始组件扫描,设置Spring上下文,在每个子项目中运行测试然后丢弃上下文,当它们在所有子项目中基本相同时。
:app:integrationTest
[..] INFO 38320 --- [ Thread-5] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@206e239d: startup date [..]; root of context hierarchy
:common:integrationTest
[..] INFO 38361 --- [ Thread-5] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@a6d8c9f: startup date [..]; root of context hierarchy
:project-a:integrationTest
[..] INFO 38362 --- [ Thread-5] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@181313ca: startup date [..]; root of context hierarchy
..
:project-n:integrationTest
[..] INFO 38363 --- [ Thread-5] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@68ab1a32: startup date [..]; root of context hierarchy
我想知道是否有办法让整个设置只运行一次,然后在所有不同的子项目中重复使用。
答案 0 :(得分:1)
我认为它不应该以你想要的方式工作 - 你的每个子项目都有自己的测试任务,其测试需要与其他项目分开执行。
另外,引用Gradle's official documentation:
测试始终在(一个或多个)单独的JVM中运行。下面的示例显示了各种配置选项。
这意味着因为您的测试任务不会共享JVM,所以它们实际上无法共享Spring上下文实例。原因是Spring缓存测试上下文的方式。以下是the official documentation的引用:
Spring TestContext框架将应用程序上下文存储在静态缓存中。这意味着上下文实际上存储在静态变量中。 换句话说,如果测试在单独的进程中执行,则静态高速缓存将在每次测试执行之间被清除,这将有效地禁用高速缓存机制。
要从缓存机制中受益,所有测试必须在同一进程或测试套件中运行。这可以通过在IDE中作为一个组执行所有测试来实现。类似地,当使用诸如Ant,Maven或Gradle之类的构建框架执行测试时,确保构建框架不在测试之间进行分配是很重要的。例如,如果Maven Surefire插件的forkMode设置为always或pertest,则TestContext框架将无法在测试类之间缓存应用程序上下文,因此构建过程的运行速度会明显变慢。
话虽如此,如果您的子项目的Spring配置确实没有区别,您可以创建一个新的子项目,仅用于集成测试目的,然后在那里执行所有集成测试,尽管您的子项目在Spring配置中没有区别,你可以合并它们或者至少以不同的方式组织它们。