spring-projects / spring-projects/spring-framework
Close all ApplicationContexts in the TestContext framework after all tests have been executed
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 60.2k
- Forks
- 38.8k
- Avg merge
- 5d 2h
- Merged PRs (30d)
- 27
Description
When using @SpringBootTest with JUnit Jupiter a pitest user had a problem when executing tests with pitest (see https://github.com/hcoles/pitest/issues/827). As far as my analysis brought me the cause is Spring Frameworks TestContext caching.
Spring caches all application contexts loaded in a static variable and reused them among different tests and test classes (TestContextManager). Unfortunately Spring does not cleanup after all(!) tests have been run assuming the JVM will be terminated immediately after tests have been executed (which in turn triggers the automatic closing behavior for application contexts). This might hold for surefire or IDE starting those tests. But Pitest reuses the JVM instance for different test suite executions (multiple invocations of JUnit Jupiter's Launcher.execute() inside the same JVM) . Thus the cached application contexts stay there and interfere with future test runs.
On the other hand Testcontainers integrates with the JUnit Jupiter Engine and uses ClosableResource hook to cleanup containers afterwards.
I've created a JUnit extension cleaning up application contexts on shutdown as a proof of concept. See SpringBootCleanup in the sample project originally provided by @jaguado-arima .
@DirtiesContext will have the same effect here and I didn't notice any differences in performance regarding this simple example. But I think it's a bad idea to add @DirtiesContext to all test classes only to be able to use pitest... if you're relying on application context caching to reduce overall testing time for a huge test suite adding @DirtiesContext to all tests for the sake of mutation testing will slow down test execution (Springs context cache has been implemented for a reason...).
@sbrannen If you consider changing the behavior as suggested I can also provide a pull request implementing the necessary changes for SpringExtension.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading TestContextManager and SpringExtension to understand how cached application contexts are retained and how JUnit Jupiter lifecycle callbacks are exposed. Compare the proposed cleanup with the ClosableResource approach described in the issue. Done means contexts are closed after repeated Launcher.execute() runs without disabling useful caching within a test run.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100