I have a set of tests based which need a spring context.
For fast test execution I want to make sure that the Spring context is initialized just once, then all the tests should be run against this context, then it should shut down.
I already tried the following approaches:
- Use
@RunWith(SpringJUnit4ClassRunner.class)
and @ContextConfiguration(MyAnnotatedConfig.class)
to initialize the spring context
- Use a
@RunWith(SpringJUnit4ClassRunner.class)
and @TestExecutionListeners({MyTestExecutionListener.class})
with a handwritten test execution listener that initializes the spring context and injects it into the concrete test classes
- Use a
@BeforeClass
listener in a base class and a static field to store the spring context, and a @AfterClass
for shutdown
With all three approaches, the spring context seems to be initialized more than once, which takes a lot of time. It seems that JUnit unloads classes while running tests, so that the content of static fields is sometimes lost.
Is there a way to make sure the spring context is initialized only once?
For fast test execution I want to make sure that the Spring context is
initialized just once, then all the tests should be run against this
context, then it should shut down.
I hate to ask the obvious, but...
Have you read the Testing chapter of the Spring Reference Manual?
Specifically, these sections explain what's going on:
- Context management and caching
- Context caching
Soooo, the TestContext framework certainly supports caching across tests within a test suite, and I should know, because I wrote it. ;)
Now as for why caching is not working for you, I can only assume that you have configured your build framework to fork for each test (or that you are running tests individually and manually within your IDE). Here's an excerpt from the last link above that might help you out:
Test suites and forked processes
The Spring TestContext framework stores application contexts in a
static cache. This means that the context is literally stored in a
static variable. In other words, if tests execute in separate
processes the static cache will be cleared between each test
execution, and this will effectively disable the caching mechanism.
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 forkMode for the Maven Surefire plug-in is set to
always or pertest, the TestContext framework will not be able to cache
application contexts between test classes and the build process will
run significantly slower as a result.
If you still experience issues after taking the above into consideration, please consider submitting a project that demonstrates your problem.
Cheers,
Sam