在多个Gradle项目中重用spring测试上下文

时间:2016-08-01 21:59:00

标签: spring gradle spring-test

我有一个典型的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

我想知道是否有办法让整个设置只运行一次,然后在所有不同的子项目中重复使用。

1 个答案:

答案 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配置中没有区别,你可以合并它们或者至少以不同的方式组织它们。