I\'m trying to cover a huge Spring Boot application with integration tests. There are lots of Spring beans within the app. It takes a while to load the Spring context.
One of the main features provided by spring framework for testing an application is the context caching mechanism to avoid exactly what you mention about the load overhead. The spring documentation says that:
Once the TestContext framework loads an
ApplicationContext
(orWebApplicationContext
) for a test, that context will be cached and reused for all subsequent tests that declare the same unique context configuration within the same test suite.
With this affirmation in mind you have to understand how the cache mechanism works to determine the best strategy on build your tests. The question here is: When spring caches the context, it stores this context in memory using what key?
. According to documentation, the key is based on some parameters of the container:
An
ApplicationContext
can be uniquely identified by the combination of configuration parameters that are used to load it. Consequently, the unique combination of configuration parameters are used to generate akey
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
(from ContextCustomizerFactory)
contextLoader
(from @ContextConfiguration)
parent
(from @ContextHierarchy)
activeProfiles
(from @ActiveProfiles)
propertySourceLocations
(from @TestPropertySource)
propertySourceProperties
(from @TestPropertySource)
resourceBasePath
(from @WebAppConfiguration)
Based on this information I may suggest you that the best practice is organize your tests in a way that they use the same set of context parameters (that is, the same cache key) to benefit from cache mechanism and avoid another context to be loaded. Spring documentation also gives an example:
..., if
TestClassA
specifies{"app-config.xml", "test-config.xml"}
for the locations (or value) attribute of @ContextConfiguration, theTestContext
framework will load the correspondingApplicationContext
and store it in a static context cache under a key that is based solely on those locations. So ifTestClassB
also defines{"app-config.xml", "test-config.xml"}
for its locations (either explicitly or implicitly through inheritance) but does not define@WebAppConfiguration
, a differentContextLoader
, different active profiles, different context initializers, different test property sources, or a different parent context, then the sameApplicationContext
will be 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.