Context Caching
一旦 TestContext 框架为测试加载了一个 ApplicationContext
(或 WebApplicationContext
),该上下文将被缓存并再次用于同一测试套件内声明相同唯一上下文配置的所有后续测试。要理解缓存如何工作的,理解什么是“唯一
”和“测试套件
”很重要。
可以通过用于加载 ApplicationContext
的配置参数的组合来唯一地标识它。因此,用于生成作为缓存上下文密钥的密钥的配置参数的唯一组合。TestContext 框架使用以下配置参数构建上下文缓存密钥:
-
locations
(from@ContextConfiguration
) -
classes
(from@ContextConfiguration
) -
contextInitializerClasses
(from@ContextConfiguration
) -
contextCustomizers
(来自ContextCustomizerFactory
)——这包括`@DynamicPropertySource` 方法以及 Spring Boot 测试支持中提供的各种特性,例如@MockBean
和@SpyBean
。 -
contextLoader
(from@ContextConfiguration
) -
parent
(from@ContextHierarchy
) -
activeProfiles
(from@ActiveProfiles
) -
propertySourceDescriptors
(from@TestPropertySource
) -
propertySourceProperties
(from@TestPropertySource
) -
resourceBasePath
(from@WebAppConfiguration
)
例如,如果 TestClassA
为 @ContextConfiguration
的 locations
(或 value
)属性指定 {"app-config.xml", "test-config.xml"}
,则 TestContext 框架将加载相应的 ApplicationContext
,并将其存储在仅根据这些位置的键下的静态上下文缓存中。所以,如果 TestClassB
也为其位置定义 {"app-config.xml", "test-config.xml"}
(显式或隐式通过继承),但没有定义 @WebAppConfiguration
、不同的 ContextLoader
、不同的活动配置文件、不同的上下文初始化程序、不同的测试属性来源或不同的父上下文,那么相同的 ApplicationContext
将由这两个测试类共享。这意味着加载应用程序上下文的设置成本只发生一次(每个测试套件),后续测试执行会快很多。
Test suites and forked processes
Spring TestContext 框架将应用程序上下文存储在一个静态缓存中。这意味着上下文从字面上存储在一个 |
上下文缓存大小受默认最大尺寸32的限制。每当达到最大尺寸时,都会使用最近最少使用(LRU)驱逐策略来驱逐和关闭陈旧的上下文。可以通过设置名为`spring.test.context.cache.maxSize`的JVM系统属性,通过命令行或构建脚本配置最大尺寸。另外,还可以通过SpringProperties
机制设置相同的属性。
由于在给定的测试套件中加载大量的应用程序上下文,可能会导致套件运行时间过长,因此确切地知道已经加载和缓存了多少个上下文通常是有益的。要查看底层上下文缓存的统计信息,您可以将 org.springframework.test.context.cache
日志类别的日志级别设置为 DEBUG
。
在不太可能发生的情况中,如果一个测试破坏了应用程序上下文并且需要重新加载(例如,通过修改 bean 定义或应用程序对象的 state),您可以使用 `@DirtiesContext`注释您的测试类或测试方法(请参阅 Spring Testing Annotations中对 `@DirtiesContext`的讨论)。这会指示 Spring 从缓存中删除上下文并在运行需要相同应用程序上下文的下一个测试之前重建应用程序上下文。请注意, `@DirtiesContext`注释的支持由 `DirtiesContextBeforeModesTestExecutionListener`和 `DirtiesContextTestExecutionListener`提供,它们默认启用。