I'm using TestContainers with Spring Boot to run unit tests for repositories like this:
@Testcontainers
@ExtendWith(SpringExtension.class)
@ActiveProfiles("itest")
@SpringBootTest(classes = RouteTestingCheapRouteDetector.class)
@ContextConfiguration(initializers = AlwaysFailingRouteRepositoryShould.Initializer.class)
@TestExecutionListeners(listeners = DependencyInjectionTestExecutionListener.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Tag("docker")
@Tag("database")
class AlwaysFailingRouteRepositoryShould {
@SuppressWarnings("rawtypes")
@Container
private static final PostgreSQLContainer database =
new PostgreSQLContainer("postgres:9.6")
.withDatabaseName("database")
.withUsername("postgres")
.withPassword("postgres");
But now I have 14 of these tests and every time a test is run a new instance of Postgres is spun up. Is it possible to reuse the same instance across all tests? The Singleton pattern doesn't help since every test starts a new application.
I've also tried testcontainers.reuse.enable=true
in .testcontainers.properties
and .withReuse(true)
, but that didn't help.
You can't use the JUnit Jupiter annotation @Container
if you want to have reusable containers. This annotation ensures to stop the container after each test.
What you need is the singleton container approach, and use e.g. @BeforeAll
to start your containers. Even though you then have .start()
in multiple tests, Testcontainers won't start a new container if you opted-in for reusability using both .withReuse(true)
on your container definition AND the following .testcontainers.properties
file in your home directory:
testcontainers.reuse.enable=true
A simple example might look like the following:
@SpringBootTest
public class SomeIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void test() {
}
}
and another integration test:
@SpringBootTest
public class SecondIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void secondTest() {
}
}
There is currently a PR that adds documentation about this
I've put together a blog post explaining how to reuse containers with Testcontainers in detail.