整合Spring配置类的性能更好?

时间:2016-08-08 19:46:16

标签: java spring junit spring-test junit-runner

我有一个基本的测试设置,TestA取决于ConfigATestB依赖于ConfigB

@Configuration
public class ConfigA {

    // define A beans

}
@Configuration
public class ConfigB {

    // define B beans

}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ConfigA.class })
public class TestA {

    @Test
    public void testA() {
        // test with A beans
    }

}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ConfigB.class })
public class TestB {

    @Test
    public void testB() {
        // test with B beans
    }

}

我想使用测试套件TestA同时运行TestBAllTests

@RunWith(Suite.class)
@SuiteClasses({ TestA.class, TestB.class })
public class AllTests {

}

目前,运行AllTests将迫使Spring在运行时加载ConfigAConfigB

ConfigAConfigB合并到ConfigC并让两个测试都改为使用ConfigC会更好吗?

@Configuration
public class ConfigC {

    // define A and B beans

}

1 个答案:

答案 0 :(得分:1)

它应该或多或少相同,性能方面 - Spring测试以任何一种方式缓存上下文,因此如果您的任何其他测试使用ContextA或ContextB,它们将从缓存重用,而不是为每个测试重新创建。使用两个单独的上下文(A和B)比使用合并的上下文有更多的开销,但它不应该那么明显。

以下是the official documentation的引用:

  

Spring TestContext Framework提供Spring ApplicationContexts和WebApplicationContexts的一致加载以及这些上下文的缓存。 支持缓存加载的上下文非常重要,因为启动时间可能会成为一个问题 - 不是因为Spring本身的开销,而是因为Spring容器实例化的对象需要时间来实例化。例如,具有50到100个Hibernate映射文件的项目可能需要10到20秒来加载映射文件,并且在每个测试夹具中运行每个测试之前产生该成本会导致整体测试运行速度变慢,从而降低开发人员的工作效率。

     

默认情况下,一旦加载,配置的ApplicationContext将重复用于每个测试。因此,每个测试套件仅产生一次设置成本,并且后续测试执行速度更快。在此上下文中,术语测试套件意味着所有测试都在同一JVM中运行 - 例如,所有测试都从Ant运行,给定项目或模块的Maven或Gradle构建。

以下是the official documentation关于上下文缓存的一些值得注意的引用:

  

Spring TestContext框架将应用程序上下文存储在静态缓存中。这意味着上下文实际上存储在静态变量中。换句话说,如果测试在单独的进程中执行,则静态高速缓存将在每次测试执行之间被清除,这将有效地禁用高速缓存机制。

     

要从缓存机制中受益,所有测试必须在同一进程或测试套件中运行。这可以通过在IDE中作为一个组执行所有测试来实现。类似地,当使用诸如Ant,Maven或Gradle之类的构建框架执行测试时,确保构建框架不在测试之间进行分配是很重要的。例如,如果Maven Surefire插件的forkMode设置为始终 pertest ,则TestContext框架将无法在测试之间缓存应用程序上下文因此,类和构建过程的运行速度会明显变慢。

     

自Spring Framework 4.3起,上下文缓存的大小受限于默认的最大大小32。每当达到最大大小时,最近使用的(LRU)驱逐策略用于驱逐和关闭陈旧的背景。通过设置名为spring.test.context.cache.maxSize的JVM系统属性,可以从命令行或构建脚本配置最大大小。作为替代方案,可以通过SpringProperties API以编程方式设置相同的属性。