spring-framework icon indicating copy to clipboard operation
spring-framework copied to clipboard

Allow `TestContextBootstrapper` to be configured globally without `@BootstrapWith`

Open EarthCitizen opened this issue 7 months ago • 2 comments

I find myself needing to customize the ContextCache so that I can run tests in parallel JUnit. Yes can be done with @BootstrapWith, but it is quite burdensome to have to add this so every single test class. This is fine for a handful of classes, but not feasible with over 100 test classes.

I have worked out how to create separate Postgres databases for each application context that loads with an ApplicationContextInitializer, which can be done globally with spring.factories, but as far as I can tell, the TestContextBootstrapper can only be overridden at the class level.

I cannot use @DirtiesContext because again, I would have to annotate every class, and this is causing my Hikari pool to get closed.

In summary, it would be much appropriated to be able to customize ContextCache globally for all tests.

EarthCitizen avatar May 11 '25 11:05 EarthCitizen

Hi @EarthCitizen,

Congratulations on submitting your first issue for the Spring Framework! 👍

Regarding your proposal, it is rather unusual to provide a custom ContextCache implementation. I am not even sure that there are many people/projects that do that in practice.

What is it exactly that you aim to achieve by supplying your own ContextCache implementation?

Have you considered implementing a TestExecutionListener that is loaded automatically for your projects?

sbrannen avatar May 12 '25 10:05 sbrannen

Hi @sbrannen I want to run Spring Boot integration tests in parallel. This is a bit of a hefty task. I am using a context customizer to create a PostgreSQL database (not server), so that each test can have 1 database all to itself in which to run Flyway, then run the tests.

In the context customizer I open a JDBC connection and create the database, if it does not exist, then setting that as the database to use in the datasource properties of the application context. The issue then comes that this application context that is set with a specific PostgreSQL database in the JDBC URL is then taken from the context cache and used simultaneously by a test class executing in parallel.

I am trying to prevent the cached application context from getting shared simultaneously. I have partially solved this by implementing my own ContextCache that does not store anything. But the burden of doing this is that every test class needs to have a @BootstrapWith annotation. But who wants to do that for over 150 test classes :-)

I have solved this by using the ByteBuddy Gradle plugin, and modifying the compiled classes to add the annotations, but I would prefer not to do this. I would much rather add an entry to spring.factories.

Also, my understanding of TestExecutionListener is that the application context is already solidified, and therefore it is too late to set properties as fundamental as the datasource URL. Is that understanding correct?

NOTE: In my original post, I said I was using an ApplicationContextInitializer, which was true, until I found out about context customizers.

EarthCitizen avatar May 13 '25 02:05 EarthCitizen