Skip to content

Start shared containers in postProcessTestInstance for PER_CLASS lifecycle#11703

Open
remal wants to merge 1 commit intotestcontainers:mainfrom
remal:fix/testcontainers-extension-post-process-instance
Open

Start shared containers in postProcessTestInstance for PER_CLASS lifecycle#11703
remal wants to merge 1 commit intotestcontainers:mainfrom
remal:fix/testcontainers-extension-post-process-instance

Conversation

@remal
Copy link
Copy Markdown

@remal remal commented Apr 13, 2026

Summary

When using @TestInstance(PER_CLASS) with frameworks like Spring Boot, Quarkus, Micronaut, or others, non-static @MethodSource factory methods may call framework beans that depend on static @Container fields to produce arguments for parameterized tests. These factory methods run after postProcessTestInstance but before beforeEach, so containers must be started earlier than beforeAll.

With PER_CLASS, postProcessTestInstance is called exactly once (same as beforeAll), making it a suitable alternative for starting shared containers. This change moves shared container startup into postProcessTestInstance for PER_CLASS lifecycle, making them available during non-static @MethodSource resolution and for other TestInstancePostProcessor extensions.

Example

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@Testcontainers
@SpringBootTest
class UserServiceTest {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");

    @Autowired
    UserService userService;

    // Non-static @MethodSource - requires PER_CLASS.
    // Calls a Spring bean that queries the database to produce test arguments.
    // Without this fix, postgres is not started yet when this method runs.
    Stream<Arguments> userArguments() {
        return userService.findAllRoles().stream()
            .map(Arguments::of);
    }

    @ParameterizedTest
    @MethodSource("userArguments")
    void should_create_user_with_role(String role) {
        // ...
    }
}

…cycle

With PER_CLASS, postProcessTestInstance runs before beforeAll. This
change starts shared containers early so they are available in
non-static @MethodSource factory methods and other
TestInstancePostProcessor extensions.

StoreAdapter now implements Startable with synchronized idempotent
start/stop to support Startables.deepStart() and prevent redundant
container lifecycle calls.
@remal remal requested a review from a team as a code owner April 13, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant