1. 概述

在这个教程中,我们将学习如何在本地开发和测试环境中重用Testcontainers

首先,我们需要确保当应用停止或测试套件完成后,不会关闭容器。接下来,我们将讨论Testcontainers特有的配置,并探讨使用Testcontainers Desktop应用程序的好处。最后,需要记住的是,重用Testcontainers是一项实验性功能,目前还不适合在持续集成管道中使用。

2. 确保不关闭容器

我们可以通过利用它们的专用JUnit 5扩展,通过@Testcontainers@Container注解,简单地为单元测试启用Testcontainers。

让我们写一个测试,启动一个Spring Boot应用,并让它连接到运行在Docker容器中的MongoDB数据库:

@Testcontainers
@SpringBootTest
class ReusableContainersLiveTest {

    @Container
    static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"));
  
    // dynamic properties and test cases
}

然而,Testcontainers的JUnit5扩展会自动启动MongoDBContainer并在测试结束后关闭它。因此,让我们移除@Testcontainers@Container注解,改为手动启动容器:

@SpringBootTest
class ReusableContainersLiveTest {
   static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"));

    @BeforeAll
    static void beforeAll() {
        mongoDBContainer.start();
    }
    
    // dynamic properties and test cases
}

另一方面,在本地开发时,我们可能使用了Spring Boot内置的Testcontainers支持。在这种情况下,我们不需要使用JUnit 5扩展,这个步骤就不再需要。

3. 管理容器生命周期

现在,我们可以完全控制容器的生命周期。我们可以配置应用以重用现有Testcontainers,并从终端手动停止它。

3.1. withReuse()方法

我们可以通过其流畅API的withReuse()方法标记一个Testcontainer为可重用:

static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"))
  .withReuse(true);

当我们首次运行测试时,我们会看到通常的Testcontainers日志,关于启动MongoDBContainer。这通常需要几秒钟:

23:56:42.383 [main] INFO tc.mongo:4.0.10 - Creating container for image: mongo:4.0.10
23:56:42.892 [main] INFO tc.mongo:4.0.10 - Container mongo:4.0.10 is starting: d5fa298bf6...
23:56:45.470 [main] INFO tc.mongo:4.0.10 - Container mongo:4.0.10 started in PT3.11239S

测试完成后,我们应该能看到容器仍在运行。例如,我们可以使用docker ps命令从终端进行检查:

重用Testcontainers

此外,只要配置不变,当重新运行测试时,容器将被重用,从而显著减少容器设置时间:

00:12:23.859 [main] INFO tc.mongo:4.0.10 - Creating container for image: mongo:4.0.10
00:12:24.190 [main] INFO tc.mongo:4.0.10 - Reusing container with ID: d5fa298b... and hash: 0702144b...
00:12:24.191 [main] INFO tc.mongo:4.0.10 - Reusing existing container (d5fa298b...) and not creating a new one
00:12:24.398 [main] INFO tc.mongo:4.0.10 - Container mongo:4.0.10 started in PT0.5555088S

最后,重用的数据库包含之前插入的文档。虽然这对于本地开发很有用,但在测试时可能会有害。如果需要从头开始,我们可以在每次测试前清空集合。

3.2. Testcontainers配置

在某些情况下,可能会出现警告,提示“请求重用,但环境不支持容器的重用”。 这发生在我们在本地Testcontainers配置中禁用了重用:

00:23:09.461 [main] INFO tc.mongo:4.0.10 - Creating container for image: mongo:4.0.10
00:23:09.463 [main] WARN tc.mongo:4.0.10 - Reuse was requested but the environment does not support the reuse of containers
To enable reuse of containers, you must set 'testcontainers.reuse.enable=true' in a file located at C:\Users\Emanuel Trandafir\.testcontainers.properties
00:23:09.544 [main] INFO tc.mongo:4.0.10 - Container mongo:4.0.10 is starting: 903dd52d7...

要解决这个问题,我们只需编辑.testcontainers.properties文件,将reuse设置为enabled

从属性中启用TC重用

3.3. 停止容器

我们可以随时从终端手动停止Docker容器。只需运行docker stop命令,然后跟随着容器ID。后续运行的应用会启动一个新的Docker容器。

4. Testcontainers Desktop

我们可以安装Testcontainer Desktop应用程序,轻松管理Testcontainers的生命周期和配置。

应用程序需要身份验证,但我们可以通过GitHub账户轻松登录。登录后,工具栏上会出现Testcontainers图标。点击后,我们会有几个选项可供选择:

Testcontainers

现在,执行之前演示的步骤就像点击按钮一样轻松。例如,我们可以通过Preferences > Enable reusable containers轻松启用或禁用可重用容器。此外,如果需要更多调试,我们还可以终止或在关机前冻结容器。

5. 总结

在这篇文章中,我们学习了如何在Java中重用Testcontainers。我们发现JUnit 5可能会在执行结束前尝试关闭容器。我们通过手动启动容器而非依赖Testcontainers的JUnit 5扩展来避免这种情况。

之后,我们讨论了withReuse()方法和其他Testcontainers特定的配置。最后,我们安装了Testcontainers Desktop应用程序,并了解了它在管理Testcontainers生命周期和配置方面的价值。

如往常一样,本文使用的完整代码可在GitHub上找到。