1. Overview
1.概述
In this tutorial, we’ll learn how to reuse Testcontainers when setting up the environment for local development and testing.
在本教程中,我们将学习如何在为本地开发和测试设置环境时重复使用 Testcontainers 。
Firstly, we’ll have to make sure we’re not shutting down the container when the application is stopped or when the test suite finishes. After that, we’ll talk about the Testcontainer–specific configuration and we’ll discuss the benefits of using the Testcontainers Desktop application. Lastly, we need to keep in mind that reusing Testcontainers is an experimental feature and it’s not yet ready to be used in CI pipelines.
首先,我们必须确保在应用程序停止或测试套件结束时不会关闭容器。之后,我们将讨论测试容器–的具体配置,并讨论使用 Testcontainers Desktop 应用程序的好处。最后,我们需要记住,重复使用 Testcontainers 是一项实验性功能,目前还不能在 CI 管道中使用。
2. Ensure the Testcontainer Isn’t Stopped
2.确保测试容器未停止运行
A straightforward way of enabling Testcontainers for our unit tests is to leverage their dedicated JUnit 5 extension through the @Testcontainers and @Container annotations.
为单元测试启用 Testcontainers 的直接方法是通过 @Testcontainers 和 @Container 注解,利用其专用的 JUnit 5 扩展。
Let’s write a test that starts a Spring Boot application and allows it to connect to a MongoDB database running in a Docker container:
让我们编写一个测试,启动 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
}
However, the Testcontainer’s JUnit5 Extension that automatically spins up MongoDBContainer will also shuts it down after the tests. Therefore, let’s remove the @Testcontainers and @Container annotations, and manually start the container instead:
然而,测试容器的 JUnit5 扩展会自动启动 MongoDBContainer 并在测试结束后关闭。因此,让我们删除 @Testcontainers 和 @Container 注解,改为手动启动容器: @Testcontainer 和 @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
}
On the other hand, we might be using Spring Boot’s built-in support for Testcontainers during local development. In this context, we won’t use the JUnit 5 extension and this step is unnecessary.
另一方面,我们可能会在本地开发过程中使用Spring Boot 内置的测试容器支持。在这种情况下,我们不会使用 JUnit 5 扩展,也就没有必要进行这一步。
3. Manage the Testcontainer Lifecycle
3.管理测试容器生命周期
Now, we can be in full control of the container’s lifecycle. We can configure the application to reuse an existing Testcontainer and we can manually stop it from the terminal.
现在,我们可以完全控制容器的生命周期。我们可以将应用程序配置为重用现有的 Testcontainer,也可以从终端手动停止它。
3.1. The withReuse() Method
3.1.withReuse() 方法
We can mark a Testcontainer as reusable by using the withReuse() method of its fluent API:
我们可以通过使用测试容器流畅应用程序接口的 withReuse() 方法,将测试容器标记为可重用:
static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"))
.withReuse(true);
When we run the test for the first time, we’ll see the usual Testcontainers logs about starting the MongoDBContainer. This usually takes a few seconds:
第一次运行测试时,我们会看到关于启动 MongoDBContainer 的 Testcontainers 日志。这通常需要几秒钟:
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
After the test finishes, we should be able to see the container still running. For example, we can check from the terminal using the docker ps command:
测试完成后,我们应该能看到容器仍在运行。例如,我们可以使用 docker ps 命令从终端进行检查:
Furthermore, when we re-run the test, the container will be reused as long as the configuration isn’t changed. As a result, the container set-up time noticeably decreases:
此外,当我们重新运行测试时,只要不更改配置,容器就会被重复使用。因此,容器设置时间明显缩短:
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
Lastly, the reused database contains previously inserted documents. Although this might be useful for local development, it may be harmful for testing. If we need to start fresh, we can simply clear the collection before each test.
最后,重复使用的数据库包含以前插入的文档。虽然这对本地开发可能有用,但对测试可能有害。如果我们需要从头开始,只需在每次测试前清除该集合即可。
3.2. Testcontainers Configuration
3.2.测试容器配置
In some cases, a warning may occur, stating that “Reuse was requested but the environment doesn’t support the reuse of containers”. This happens when the reuse is disabled on our local Testcontainers configuration:
在某些情况下,可能会出现警告,提示“已请求重用,但环境不支持重用容器”。当我们的本地 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...
To fix it, we can simply edit the .testcontainers.properties file and set reuse as enabled:
要解决这个问题,我们只需编辑 .testcontainers.properties 文件,并将 reuse 设置为 enabled:
3.3. Stopping the Container
3.3.停止容器
We can manually stop the Docker container whenever we want, from the terminal. To do so, we only need to run the docker stop command, followed by the container ID. Future executions of the application spin up a new Docker container.
我们可以随时从终端手动停止 Docker 容器。为此,我们只需运行 docker stop 命令,然后输入容器 ID。应用程序的未来执行将启动一个新的 Docker 容器。
4. Testcontainers Desktop
4.测试容器桌面
We can install the Testcontainer Desktop application to easily manage the lifecycle and configuration of our Testcontainers.
我们可以安装 Testcontainer Desktop 应用程序,轻松管理测试容器的生命周期和配置。
The application requires authentication, but we can easily log in using a GitHub account. After signing in, we’ll see the Testcontainers icon in the toolbar. If we click on it, we’ll have a few options to choose from:
应用程序需要身份验证,但我们可以使用 GitHub 账户轻松登录。登录后,我们会在工具栏中看到 Testcontainers 图标。点击后,我们将有几个选项可供选择:
Now, executing the previously demonstrated steps is as effortless as the click of a button. For instance, we can enable or disable reusable containers with ease via Preferences > Enable reusable containers. Furthermore, we have the capability to terminate the containers or freeze them before the shutdown, if more debugging is needed.
现在,执行之前演示的步骤就像点击按钮一样轻松。例如,我们可以通过 Preferences > Enable reusable containers 轻松启用或禁用可重复使用的容器。此外,如果需要进行更多调试,我们还可以在关闭前终止或冻结容器。
5. Conclusion
5.结论
In this article, we’ve learned how to reuse Testcontainers in Java. We discovered that JUnit 5 might try to shut down the container before finishing the execution. We avoided this by manually starting the containers instead of relying on the Testcontainers’ JUnit 5 extension.
在本文中,我们学习了如何在 Java 中重用测试容器。我们发现,JUnit 5 可能会在完成执行之前尝试关闭容器。我们通过手动启动容器而不是依赖 Testcontainers 的 JUnit 5 扩展来避免这种情况。
After that, we discussed the withReuse() method and other Testcontainer-specific configurations. Finally, we installed the Testcontainers Desktop application, and we saw how it can be a valuable asset for double-checking configurations when it comes to managing the Testcontainers’ lifecycle.
之后,我们讨论了 withReuse() 方法和其他特定于 Testcontainer 的配置。最后,我们安装了 Testcontainers Desktop 应用程序,并了解了在管理 Testcontainers 生命周期时,它如何成为反复检查配置的宝贵资产。
As always, the complete code used in this article is available over on GitHub.
与往常一样,本文中使用的完整代码可在 GitHub 上获取。