上下文缓存
一旦 TestContext 框架为测试加载 ApplicationContext(或 WebApplicationContext),该上下文就会被缓存并重用于同一测试套件中声明相同唯一上下文配置的所有后续测试。为了理解缓存如何工作,理解“唯一”和“测试套件”的含义非常重要。
ApplicationContext 可以通过用于加载它的配置参数组合进行唯一标识。因此,配置参数的唯一组合用于生成上下文缓存的键。TestContext 框架使用以下配置参数来构建上下文缓存键:
-
locations(来自@ContextConfiguration) -
classes(来自@ContextConfiguration) -
contextInitializerClasses(来自@ContextConfiguration) -
contextCustomizers(来自ContextCustomizerFactory)——这包括@DynamicPropertySource方法、Bean 覆盖(例如@TestBean、@MockitoBean、@MockitoSpyBean等),以及 Spring Boot 测试支持中的各种特性。 -
contextLoader(来自@ContextConfiguration) -
parent(来自@ContextHierarchy) -
activeProfiles(来自@ActiveProfiles) -
propertySourceDescriptors(来自@TestPropertySource) -
propertySourceProperties(来自@TestPropertySource) -
resourceBasePath(来自@WebAppConfiguration)
例如,如果 TestClassA 为 @ContextConfiguration 的 locations(或 value)属性指定 {"app-config.xml", "test-config.xml"},TestContext 框架会加载相应的 ApplicationContext 并将其存储在 static 上下文缓存中,键仅基于这些位置。因此,如果 TestClassB 也为其位置定义 {"app-config.xml", "test-config.xml"}(无论是显式还是通过继承隐式),但没有定义 @WebAppConfiguration、不同的 ContextLoader、不同的活动配置文件、不同的上下文初始化器、不同的上下文定制器、不同的测试或动态属性源,或者不同的父上下文,那么相同的 ApplicationContext 将由这两个测试类共享。这意味着加载应用程序上下文的设置成本只发生一次(每个测试套件),并且后续的测试执行会快得多。
|
测试套件和分叉进程
Spring TestContext 框架将应用程序上下文存储在静态缓存中。这意味着上下文实际上存储在 |
上下文缓存的大小上限默认为 32。一旦达到最大大小,将使用最近最少使用(LRU)逐出策略来逐出和关闭陈旧的上下文。您可以通过设置名为 spring.test.context.cache.maxSize 的 JVM 系统属性,从命令行或构建脚本配置最大大小。作为替代方案,您可以通过
SpringProperties 机制设置相同的属性。
自 Spring Framework 7.0 起,存储在上下文缓存中的应用程序上下文在不再主动使用时将被_暂停_,并在下次从缓存中检索上下文时自动_重新启动_。具体来说,后者将重新启动应用程序上下文中的所有自动启动 Bean,从而有效地恢复生命周期状态。这确保了在上下文未被测试使用时,上下文中的后台进程不会主动运行。例如,JMS 监听器容器、计划任务以及上下文中实现 Lifecycle 或 SmartLifecycle 的任何其他组件将处于“停止”状态,直到上下文再次被测试使用。但是请注意,SmartLifecycle 组件可以通过从 SmartLifecycle#isPauseable() 返回 false 来选择不暂停。
由于在给定测试套件中加载大量应用程序上下文可能会导致套件运行时间过长,因此了解已加载和缓存的上下文数量通常是有益的。要查看底层上下文缓存的统计信息,您可以将 org.springframework.test.context.cache 日志类别的日志级别设置为 DEBUG。
在极少数情况下,如果测试破坏了应用程序上下文并需要重新加载(例如,通过修改 Bean 定义或应用程序对象的状态),您可以使用 @DirtiesContext 注解您的测试类或测试方法(请参阅
Spring 测试注解 中关于 @DirtiesContext 的讨论)。
这会指示 Spring 从缓存中移除上下文并在运行下一个需要相同应用程序上下文的测试之前重建应用程序上下文。请注意,对 @DirtiesContext 注解的支持由 DirtiesContextBeforeModesTestExecutionListener 和 DirtiesContextTestExecutionListener 提供,它们默认启用。
|
ApplicationContext 生命周期和控制台日志记录
当您需要调试使用 Spring TestContext 框架执行的测试时,分析控制台输出(即输出到
如果上下文根据 |