如何在多个SpringBootTests之间重用测试容器?

我正在使用带有Spring Boot的TestContainers来运行存储库的单元测试,如下所示:

@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实例。是否可以在所有测试中重用同一实例?单例模式没有帮助,因为每个测试都会启动一个新的应用程序。

我也尝试过和,但这没有帮助。testcontainers.reuse.enable=true.testcontainers.properties.withReuse(true)


答案 1

如果你想拥有可重用的容器,则不能使用JUnit Jupiter注释。此注释可确保在每次测试后停止容器。@Container

您需要的是单例容器方法,并使用例如 以启动容器。即使您随后进行了多次测试,如果您选择使用容器定义和主目录中的以下文件来实现可重用性,Testcontainers也不会启动新容器:@BeforeAll.start().withReuse(true).testcontainers.properties

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添加了有关此内容的文档

我整理了一篇博客文章,详细解释了如何用Testcontainers重用容器


答案 2

如果您决定继续使用单例模式,请注意“通过 JDBC URL 方案启动的数据库容器”中的警告。我花了几个小时才注意到,即使我使用的是单例模式,也总是在不同的端口上创建一个映射的额外容器。

总之,如果需要使用单例模式,请不要使用测试容器 JDBC(无主机)URI,例如 。jdbc:tc:postgresql:<image-tag>:///<databasename>


推荐