如何在多个 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>