停止接受测试,使用测试范围
#测试 #java #testcontainers #integrationtest

开发人员在工作日需要与两个或更多系统一起工作。这些系统的质量取决于集成和单位测试。它需要管道和大型基础设施。管道在类似于称为“登台的生产服务器”的服务器中运行测试。根据[12],维护服务器的成本为2k至15k。取决于公司,这是高成本。当需要生产环境和另一个舞台的环境时,成本会重复。但是,在登台环境中运行测试的管道可能会导致依赖系统下降或团队部署新版本时会导致许多错误的正错误。此外,开发人员团队可以导致其他问题,要安装的高平台数量,平台版本之间的差异,更新平台版本的难度以及平台在生产和开发人员环境中的差异。

REST API系统至少需要一个数据库和一个消息代理系统。但是,真正的市场系统需要缓存服务,并且根据市场要求,存储系统和平台列表可以增加很多。因此,要在本地运行系统,开发人员需要安装所有平台。当具有更多系统时,该数字可以呈指数级增加。开发人员需要为每个系统安装每个平台的不同版本。另一个问题是,开发人员可以安装具有版本X 的平台和另一个开发人员安装版本Z 。第一个开发人员可以创建在版本X 中工作的测试,但在版本z 中不起作用。因此,第二个开发人员无法运行测试,并且由于版本的差异而需要帮助发现错误。一个类似的问题是,当生产中发生错误并且由于版本的差异而不会在本地发生。此外,当新开发人员试图设置开发人员环境时,克隆的代码没有平台的版本。因此,他需要安装可用的持续版本来运行测试。历史的结束是,许多测试将失败,在最坏的情况下,他不会在没有高级开发人员的帮助下在本地运行该系统。

本文旨在帮助开发人员浪费更少的钱,并继续提高系统交付质量。我们将展示如何使用两种工具,即Docker和TestContainers来降低使用Java测试系统的成本。使用Docker为您的依赖项提供基础架构,而TestContainers是一个库,可允许您为测试创建不同的方案。因此,读者将学习如何使用这些工具轻松创建您的测试环境,成本最低,并且与开发人员团队无困难。

用Docker创建基础架构

所有软件都需要一些基础架构,例如数据库或消息代理。开发人员在开发阶段测试该软件的基本过程是手动创建工作站中的环境。 Docker是一种工具,可以帮助开发人员在容器中运行每个依赖关系。在Docker Official中找到有关Docker的更多信息。

使用TestContainers库进行配置

TestContainers使得在测试平台开始时可以轻松为您的测试创建所有环境。它允许您以编程方式创建任何类型的容器。您可以设置容器的端口,网络,版本,并为每个测试设置正确的配置。在TestContainers quick start中查找更多信息。

使用测试容器

首先,您需要将库添加到依赖项管理中。在Gradle中,您可以做到这一点:

testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
testImplementation "org.testcontainers:testcontainers:1.17.2"
testImplementation "org.testcontainers:junit-jupiter:1.17.2"

您的测试,共享容器和本地容器中有两种模式可以设置容器。第一种类型是仅在JVM停止时创建和停止容器,第二类是为每个方法测试创建一个新容器。但是,在这两种模式下,您都可以从创建一堂课到容器或设置为您创建容器的库创建一个用于测试的容器。您可以在下面看到一个示例,为Postgres创建一个容器类:

public class CustomPostgresContainer extends PostgreSQLContainer<CustomPostgresContainer> {

   public CustomPostgresContainer() {
      super(DockerImageName.parse("postgres:13-alpine").asCompatibleSubstituteFor("postgres"));
      withUsername("postgres");
      withPassword("<password>");
      withDatabaseName("<db-name>");
      withExposedPorts(5432);

      start();
   }
}

之后,您可以使用此类为测试创建一个容器。这里的观察是需要一个具有PostgreSQLContainer类的新依赖性:

testImplementation 'org.testcontainers:postgresql:1.17.6'

现在使用该类看一个示例测试:


public class ExampleRestIT extends IntegrationTest {

   private CustomPostgresContainer postgresContainer = new CustomPostgresContainer();

   @Test public void shouldStartingAContainer() {
      postgresContainer.start();

      Assertions.assertTrue(postgresContainer.isRunning());
   }
}

这种情况是控制容器。有一个注释将告知测试范围,每个方法测试需要启动哪些容器并停止。您可以在下面看到一个示例:

@Testcontainers
public class ExampleRestIT extends IntegrationTest {

   @Container
   private CustomPostgresContainer postgresContainer = new CustomPostgresContainer();

   @Test public void shouldStartingAContainer() {
      // postgresContainer.start(); ------ Dont need any more

      Assertions.assertTrue(postgresContainer.isRunning());
   }
}

使用网络平台

但这是一个没有任何Web平台(例如QuarkusSpring)的测试。例如,Quarkus的测试范围设置需要一些新类。但是,在我们需要了解我们的要求之前。根据您的方案,您需要启动和停止每类测试的容器。在另一个测试中,您可以重复使用一个容器。对于第一种情况,创建一个实现QuarkusTestResourceLifecycleManager的类。例如下面的类:

public class SharedContainerResource implements QuarkusTestResourceLifecycleManager {
    protected CustomPostgresContainer POSTGRES_CONTAINER = new CustomPostgresContainer();

    @Override
    public Map<String, String> start() {
        return POSTGRES_CONTAINER.configureProperties();
    }

    @Override
    public void stop() {
        POSTGRES_CONTAINER.stop();
    }
}

使用此类,您可以控制容器的创建和破坏。当Quarkus上下文启动时,它将创建容器。之后,它将调用该方法开始获取所有属性以替换这些值。例如,要连接到Postgres数据库的端口。当Quarkus上下文停止时,请调用方法停止,我们可以停止容器。如果我们需要每个测试类的新容器,则可以删除停止的容器并创建这样的静态字段:

public class SharedContainerResource implements QuarkusTestResourceLifecycleManager {
    protected static final CustomPostgresContainer POSTGRES_CONTAINER = new CustomPostgresContainer();

    @Override
    public Map<String, String> start() {
        return POSTGRES_CONTAINER.configureProperties();
    }

    @Override
    public void stop() {
        // removed the stop of the container. The testContainer library will destroy automatically when the JVM stops
    }
}

使用该配置,我们可以为上下文创建一个容器,在执行结束时,TestContainer库将自动停止容器。我们为您提供独立测试并且不需要新基础架构(例如干净的数据库)的方案推荐此功能。使用此模式,您可以浪费比使用本地容器更少的时间进行测试。

您可以从官方文档中从TestContainers quick start中找到更多详细信息。

结论

在本文中,我们展示了如何与容器创建集成测试以模拟任何类型的环境。我们还显示了设置的两种模式在您的测试中及其之间的差异。另外,我们举例说明了使用Quarkus平台使用库测试范围的示例。

但是,在本文中,我们没有介绍如何使用诸如Spring等其他Web平台的测试范围。此外,更多的库与其他语言集成在一起。社区在TestContainers's github account中创建了许多存储库来分享与其他语言的约束。

如果您喜欢此内容,并想更多地谈论您一天中与测试保持一致的问题,那么本周您有一个特别的机会在my calendly上预订。很高兴帮助您解决问题。