Как повторно использовать Testcontainers между несколькими SpringBootTests?

Я использую TestContainers с Spring Boot для запуска модульных тестов для таких репозиториев:

@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 не помогает, поскольку каждый тест запускает новое приложение.

Я также пробовал testcontainers.reuse.enable=true в .testcontainers.properties и .withReuse(true), но это не помогло.


person Martin Schröder    schedule 17.06.2020    source источник
comment
Вы пробовали опцию withReuse (true)?   -  person P3trur0    schedule 17.06.2020
comment
@ P3trur0: Да. И testcontainers.reuse.enable=true - не помогает.   -  person Martin Schröder    schedule 17.06.2020
comment
Попробуйте поместить экземпляр контейнера в отдельный @TestConfiguration как @Bean, а затем импортируйте эту конфигурацию во все соответствующие тесты.   -  person Nikolai Shevchenko    schedule 17.06.2020
comment
@NikolaiShevchenko: Пробовал, но он нужен в @ContextConfiguration(initializers, и я не могу заставить его там работать.   -  person Martin Schröder    schedule 17.06.2020


Ответы (2)


Вы не можете использовать аннотацию JUnit Jupiter @Container, если хотите иметь многоразовые контейнеры. Эта аннотация гарантирует остановку контейнера после каждого теста.

Вам нужен одноэлементный контейнерный подход и используйте, например, @BeforeAll, чтобы запустить ваши контейнеры. Даже если после этого у вас будет .start() в нескольких тестах, Testcontainers не запустит новый контейнер, если вы включили возможность повторного использования, используя как .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.

person rieckpil    schedule 18.06.2020
comment
Большое спасибо. Затем мне также нужно увеличить мой max_connections на .withCommand("postgres -c max_connections=200"). Как я могу контролировать срок службы многоразовых контейнеров? - person Martin Schröder; 18.06.2020
comment
Я не могу ответить на этот вопрос. Возможно, стоит взглянуть на PR, который представил эту функцию: github.com/testcontainers/ testcontainers-java / pull / 1781 - person rieckpil; 18.06.2020
comment
Где задокументирован testcontainers.reuse.enable = true? - person Abbadon; 20.11.2020
comment
Есть ли способ настроить testcontainers.reuse.enable=true где-нибудь? Я не хочу, чтобы многоразовые контейнеры зависели от конфигурации ноутбука разработчика. - person vault; 23.02.2021
comment
Да, есть несколько способов настроить это свойство. Взгляните на раздел конфигураций документации Testcontainers. - person rieckpil; 23.02.2021

Я не уверен, как @Testcontainers работает, но подозреваю, что это может сработать для каждого класса.

Просто сделайте свой синглтон статическим, как описано в шаблоне синглтона, и получите его в каждом тесте из своего сиглтона. держатель, не определяйте его в каждом тестовом классе.

person Vitaly Chura    schedule 17.06.2020
comment
Шаблон Singleton не помогает, поскольку каждый тест запускает новое приложение. - person Martin Schröder; 17.06.2020