Context Caching
Once the TestContext framework loads an ApplicationContext
(or WebApplicationContext
)
for a test, that context is cached and reused for all subsequent tests that declare the
same unique context configuration within the same test suite. To understand how caching
works, it is important to understand what is meant by “unique” and “test suite.”
An ApplicationContext
can be uniquely identified by the combination of configuration
parameters that is used to load it. Consequently, the unique combination of configuration
parameters is used to generate a key under which the context is cached. The TestContext
framework uses the following configuration parameters to build the context cache key:
-
locations
(from@ContextConfiguration
) -
classes
(from@ContextConfiguration
) -
contextInitializerClasses
(from@ContextConfiguration
) -
contextCustomizers
(fromContextCustomizerFactory
) – this includes@DynamicPropertySource
methods as well as various features from Infra App’s testing support such as@MockBean
and@SpyBean
. -
contextLoader
(from@ContextConfiguration
) -
parent
(from@ContextHierarchy
) -
activeProfiles
(from@ActiveProfiles
) -
propertySourceDescriptors
(from@TestPropertySource
) -
propertySourceProperties
(from@TestPropertySource
) -
resourceBasePath
(from@WebAppConfiguration
)
For example, if TestClassA
specifies {"app-config.xml", "test-config.xml"}
for the
locations
(or value
) attribute of @ContextConfiguration
, the TestContext framework
loads the corresponding ApplicationContext
and stores it in a static
context cache
under a key that is based solely on those locations. So, if TestClassB
also defines
{"app-config.xml", "test-config.xml"}
for its locations (either explicitly or
implicitly through inheritance) but does not define @WebAppConfiguration
, a different
ContextLoader
, different active profiles, different context initializers, different
test property sources, or a different parent context, then the same ApplicationContext
is shared by both test classes. This means that the setup cost for loading an application
context is incurred only once (per test suite), and subsequent test execution is much
faster.
Test suites and forked processes
The Infra TestContext framework stores application contexts in a static cache. This
means that the context is literally stored in a To benefit from the caching mechanism, all tests must run within the same process or test
suite. This can be achieved by executing all tests as a group within an IDE. Similarly,
when executing tests with a build framework such as Ant, Maven, or Gradle, it is
important to make sure that the build framework does not fork between tests. For example,
if the
|
The size of the context cache is bounded with a default maximum size of 32. Whenever the
maximum size is reached, a least recently used (LRU) eviction policy is used to evict and
close stale contexts. You can configure the maximum size from the command line or a build
script by setting a JVM system property named infra.test.context.cache.maxSize
. As an
alternative, you can set the same property via the
InfraProperties
mechanism.
Since having a large number of application contexts loaded within a given test suite can
cause the suite to take an unnecessarily long time to run, it is often beneficial to
know exactly how many contexts have been loaded and cached. To view the statistics for
the underlying context cache, you can set the log level for the
cn.taketoday.test.context.cache
logging category to DEBUG
.
In the unlikely case that a test corrupts the application context and requires reloading
(for example, by modifying a bean definition or the state of an application object), you
can annotate your test class or test method with @DirtiesContext
(see the discussion of
@DirtiesContext
in Infra Testing Annotations
). This instructs Infra to remove the context from the cache and rebuild
the application context before running the next test that requires the same application
context. Note that support for the @DirtiesContext
annotation is provided by the
DirtiesContextBeforeModesTestExecutionListener
and the
DirtiesContextTestExecutionListener
, which are enabled by default.
ApplicationContext lifecycle and console logging
When you need to debug a test executed with the Infra TestContext Framework, it can be
useful to analyze the console output (that is, output to the With regard to console logging triggered by the TODAY Framework itself or by components
registered in the The The
If the context is closed according to When a Infra |