我正在进行典型的 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
的共同任务,它运行所有集成测试套件(类)。这些类继承自用典型的 spring 测试内容注释的公共(public)父类:
@ContextConfiguration // needed until Spock supports @SpringBootTest
@SpringBootTest(classes = IntegrationTestConfiguration)
@ActiveProfiles("test")
class BaseTest extends Specification {
IntegrationTestConfiguration
是用 @EnableAutoConfiguration
注释的 @Configuration
类,并且只预定义了一些 beans,而不是实际的完整 @SpringBootApplication
类。
问题是调用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
我想知道是否有一种方法可以让整个设置只运行一次,然后在所有不同的子项目中重复使用。
最佳答案
我不认为它应该按照您希望的方式工作 - 您的每个子项目都有自己的测试任务,并且其测试需要与其他项目分开执行。
此外,引用自Gradle's official documentation :
Test are always run in (one or more) separate JVMs. The sample below shows various configuration options.
这意味着因为您的测试任务不会共享 JVM,所以它们实际上不能共享 Spring 上下文实例。原因是 Spring 缓存测试上下文的方式。这是来自 the official documentation 的引述:
The Spring TestContext framework stores application contexts in a static cache. This means that the context is literally stored in a static variable. In other words, if tests execute in separate processes the static cache will be cleared between each test execution, and this will effectively disable the caching mechanism.
To benefit from the caching mechanism, all tests must run within the same process or test suite. This can be achieved by executing all tests as a group within an IDE. Similarly, when executing tests with a build framework such as Ant, Maven, or Gradle it is important to make sure that the build framework does not fork between tests. For example, if the forkMode for the Maven Surefire plug-in is set to always or pertest, the TestContext framework will not be able to cache application contexts between test classes and the build process will run significantly slower as a result.
也就是说,如果您的子项目的 Spring 配置确实没有区别,您可以创建一个新的子项目,仅用于集成测试目的,然后在那里执行所有集成测试,尽管如果您的子项目Spring 配置没有区别,您也许可以合并它们或至少以不同方式组织它们。
关于spring - 跨多个 Gradle 项目重用 spring 测试上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38708793/