Spring测试环境最佳实践

VB_*_*VB_ 9 java spring design-patterns spring-test spring-boot

我试图用集成测试覆盖一个巨大的Spring Boot应用程序.应用程序中有很多Spring bean.加载Spring上下文需要一段时间.

所以我想知道 -

  • Spring是否足够聪明,可以在位于不同类中的多个集成测试之间共享相同的上下文?我的意思是避免初始化每个测试类的重量级上下文.
  • 当测试1,2,4使用TestContextOne和测试3,5使用时会发生什么TestContextTwo?Spring会以1,2,4,3,5的顺序启动它们吗?或者Spring在内存中保留两个上下文?

PS换句话说,通常的做法是为所有集成测试使用单个"完整"Spring Context,而不是为每个测试编写单独的Spring?

小智 10

Spring框架提供的用于测试应用程序的主要功能之一是上下文缓存机制,以避免您提到的负载开销.春季文档说:

一旦TestContext框架加载ApplicationContext(或WebApplicationContext)测试,该上下文将被缓存并重用于在同一测试套件中声明相同唯一上下文配置的所有后续测试.

考虑到这一点,您必须了解缓存机制如何确定构建测试的最佳策略.这里的问题是:When spring caches the context, it stores this context in memory using what key?.根据文档,关键是基于容器的一些参数:

ApplicationContext可以通过用于加载它的配置参数的组合来唯一地标识An .因此,配置参数的唯一组合用于生成key高速缓存上下文的用户.TestContext框架使用以下配置参数来构建上下文缓存键:

locations(来自@ContextConfiguration)
classes(来自@ContextConfiguration)
contextInitializerClasses(来自@ContextConfiguration)
contextCustomizers(来自
contextLoader@ContextConfiguration)
parent(来自@ContextHierarchy)
activeProfiles(来自@ActiveProfiles)
propertySourceLocations(来自@TestPropertySource)
propertySourceProperties(来自@TestPropertySource)
resourceBasePath(来自@WebAppConfiguration)

根据这些信息,我可能会建议您最佳实践是组织您的测试,使用相同的上下文参数集(即相同的缓存键)以从缓存机制中受益并避免加载另一个上下文.Spring文档也给出了一个例子:

...,如果TestClassA为@ContextConfiguration的locations(或value)属性指定{"app-config.xml","test-config.xml"},TestContext框架将加载相应的ApplicationContext并将其存储在静态上下文中在仅基于这些位置的密钥下缓存.因此,如果TestClassB还为其位置定义了{"app-config.xml","test-config.xml"}(通过继承显式或隐式),但没有定义@WebAppConfiguration,不同的ContextLoader,不同的活动配置文件,不同的上下文初始化器,不同的测试属性源或不同的父上下文,然后两个测试类将共享相同的ApplicationContext.这意味着加载应用程序上下文的设置成本仅产生一次(每个测试套件),并且后续测试执行要快得多.