返回

使用 Testcontainers 在多个测试类中避免断言失败

java

在 Testcontainers 中使用多个测试类时解决断言失败问题

简介

在使用 Testcontainers 时,在多个测试类中进行测试可能会导致断言失败。本文探讨了这一问题并提供了详细的解决方案,帮助你解决此类问题。

问题

当你使用 Testcontainers 在多个测试类中进行测试时,除第一个测试类外的其他测试类可能会出现断言失败。尽管测试日志表明测试用例已成功完成,但断言仍然失败。

原因

使用 Testcontainers 时,为每个测试方法启动一个容器至关重要。当使用 singleton 测试容器模式时,容器会在第一次测试运行时启动,并在后续测试中重用。然而,当使用 @Testcontainers 注解时,Testcontainers 会自动为每个测试方法启动一个容器。

在使用多个测试类的情况下,第一个测试类使用 @Testcontainers 注解,因此容器在该测试类中正确启动。但是,后续测试类使用 @Singleton 模式,导致容器在后续测试中无法正确启动,从而导致断言失败。

解决方案

为了解决此问题,你需要将 @Container 注解添加到抽象测试容器类 AbstractTestcontainersTest,如下所示:

@Slf4j
@Testcontainers
public abstract class AbstractTestcontainersTest {

    private final static String DATABASE_NAME = "test_name";

    @Container
    public static final PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("postgres:12")
            .withReuse(true)
            .withDatabaseName(DATABASE_NAME);

    static {
        postgresContainer.start();
      
    }

    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgresContainer::getJdbcUrl);
        registry.add("spring.datasource.username", postgresContainer::getUsername);
        registry.add("spring.datasource.password", postgresContainer::getPassword);
        registry.add("spring.datasource.driver-class-name", postgresContainer::getDriverClassName);

    }
}

实现原理

通过将 @Container 注解添加到抽象测试容器类,你可以确保在使用 Testcontainers 时为每个测试方法启动一个新的容器。这样可以解决断言失败的问题,因为每个测试方法都会使用一个新的容器实例。

总结

通过遵循本指南中概述的解决方案,你可以在使用 Testcontainers 时在多个测试类中消除断言失败问题。记住,在使用 Testcontainers 时,为每个测试方法启动一个容器至关重要,添加 @Container 注解是解决此问题的有效方法。

常见问题解答

  • 问:为什么在 Testcontainers 中需要为每个测试方法启动一个容器?
    • 答: 因为 Testcontainers 使用 singleton 模式,这可能会导致后续测试中容器状态不一致,从而导致断言失败。
  • 问:除了使用 @Container 注解之外,还有其他解决此问题的方案吗?
    • 答: 你还可以使用 Testcontainers 的 @TestcontainersResource 注解,该注解允许你在每个测试类中显式启动和停止容器。
  • 问:在使用 Testcontainers 时,我需要遵循哪些最佳实践?
    • 答: 确保为每个测试方法启动一个容器、使用强有力的断言来验证测试结果、使用恰当的数据源设置并管理容器的生命周期。
  • 问:Testcontainers 是否可以在其他编程语言中使用?
    • 答: 是的,Testcontainers 支持多种编程语言,包括 Java、Python、Node.js 和 .NET。
  • 问:在哪里可以了解更多有关 Testcontainers 的信息?