如何在多个 SpringBootTest 之间复用 Testcontainer?
How to reuse Testcontainers between multiple SpringBootTests?
我正在使用 TestContainers Spring 启动到 运行 存储库的单元测试,如下所示:
@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");
但现在我有 14 个这样的测试,每次测试 运行 都会启动一个新的 Postgres 实例。是否可以在所有测试中重复使用同一个实例? Singleton pattern 没有帮助,因为每个测试都会启动一个新应用程序。
我也在 .testcontainers.properties
和 .withReuse(true)
中尝试了 testcontainers.reuse.enable=true
,但没有帮助。
我不确定 @Testcontainers
是如何工作的,但我怀疑它可能会根据 class 工作。
只需按照 Singleton pattern 中的说明使您的单例静态化
并在每个测试中从你的 signleton 持有者那里得到它,不要在每个测试中定义它 class.
如果您想拥有可重用的容器,则不能使用 JUnit Jupiter 注释 @Container
。此注释确保停止容器 after each test.
您需要的是单例容器方法,并使用例如@BeforeAll
启动您的容器。即使您随后在多个测试中有 .start()
,如果您选择使用容器定义中的 .withReuse(true)
和下面的 .testcontainers.properties
文件来实现可重用性,Testcontainers 也不会启动新容器您的主目录:
testcontainers.reuse.enable=true
一个简单的示例可能如下所示:
@SpringBootTest
public class SomeIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void test() {
}
}
和另一个集成测试:
@SpringBootTest
public class SecondIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void secondTest() {
}
}
目前有一个PR that adds documentation关于这个
我整理了一篇博客 post 详细解释 how to reuse containers with Testcontainers。
如果您决定继续 singleton pattern, mind the warning in "Database containers launched via JDBC URL scheme". I took hours till I note that, even though I was using the singleton pattern,则会始终创建一个映射到不同端口的额外容器。
总而言之,如果需要使用 singleton pattern.
,请不要使用测试容器 JDBC(无主机)URI,例如 jdbc:tc:postgresql:<image-tag>:///<databasename>
我正在使用 TestContainers Spring 启动到 运行 存储库的单元测试,如下所示:
@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");
但现在我有 14 个这样的测试,每次测试 运行 都会启动一个新的 Postgres 实例。是否可以在所有测试中重复使用同一个实例? Singleton pattern 没有帮助,因为每个测试都会启动一个新应用程序。
我也在 .testcontainers.properties
和 .withReuse(true)
中尝试了 testcontainers.reuse.enable=true
,但没有帮助。
我不确定 @Testcontainers
是如何工作的,但我怀疑它可能会根据 class 工作。
只需按照 Singleton pattern 中的说明使您的单例静态化 并在每个测试中从你的 signleton 持有者那里得到它,不要在每个测试中定义它 class.
如果您想拥有可重用的容器,则不能使用 JUnit Jupiter 注释 @Container
。此注释确保停止容器 after each test.
您需要的是单例容器方法,并使用例如@BeforeAll
启动您的容器。即使您随后在多个测试中有 .start()
,如果您选择使用容器定义中的 .withReuse(true)
和下面的 .testcontainers.properties
文件来实现可重用性,Testcontainers 也不会启动新容器您的主目录:
testcontainers.reuse.enable=true
一个简单的示例可能如下所示:
@SpringBootTest
public class SomeIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void test() {
}
}
和另一个集成测试:
@SpringBootTest
public class SecondIT {
public static GenericContainer postgreSQLContainer = new PostgreSQLContainer().
withReuse(true);
@BeforeAll
public static void beforeAll() {
postgreSQLContainer.start();
}
@Test
public void secondTest() {
}
}
目前有一个PR that adds documentation关于这个
我整理了一篇博客 post 详细解释 how to reuse containers with Testcontainers。
如果您决定继续 singleton pattern, mind the warning in "Database containers launched via JDBC URL scheme". I took hours till I note that, even though I was using the singleton pattern,则会始终创建一个映射到不同端口的额外容器。
总而言之,如果需要使用 singleton pattern.
,请不要使用测试容器 JDBC(无主机)URI,例如jdbc:tc:postgresql:<image-tag>:///<databasename>