Testcontainers Support
除了 using Testcontainers for integration testing 之外,在开发时也可以使用它们。下一节将提供有关此内容的更多详细信息。
As well as using Testcontainers for integration testing, it’s also possible to use them at development time. The next sections will provide more details about that.
Using Testcontainers at Development Time
这种方法允许开发人员快速启动应用程序依赖的服务的容器,从而无需手动配置数据库服务器等内容。以这种方式使用 Testcontainers 提供的功能与 Docker Compose 类似,只不过你的容器配置用 Java 编写,而不是 YAML。
This approach allows developers to quickly start containers for the services that the application depends on, removing the need to manually provision things like database servers. Using Testcontainers in this way provides functionality similar to Docker Compose, except that your container configuration is in Java rather than YAML.
要在开发时使用 Testcontainers,你需要使用 “test” 类路径而不是 “main” 来启动应用程序。这将允许你访问所有已声明的测试依赖关系,并为你提供一个编写测试配置的自然位置。
To use Testcontainers at development time you need to launch your application using your “test” classpath rather than “main”. This will allow you to access all declared test dependencies and give you a natural place to write your test configuration.
要创建应用程序的可测试启动版本,你应该在 src/test
目录中创建一个 “Application” 类。例如,如果你的主应用程序在 src/main/java/com/example/MyApplication.java
,你应该创建 src/test/java/com/example/TestMyApplication.java
。
To create a test launchable version of your application you should create an “Application” class in the src/test
directory.
For example, if your main application is in src/main/java/com/example/MyApplication.java
, you should create src/test/java/com/example/TestMyApplication.java
TestMyApplication
类可以使用 SpringApplication.from(…)
方法启动真正的应用程序:
The TestMyApplication
class can use the SpringApplication.from(…)
method to launch the real application:
你还需要定义要与应用程序一起启动的 Container
实例。为此,你需要确保将 spring-boot-testcontainers
模块已添加为 test
依赖关系。完成此操作后,你可以创建一个 @TestConfiguration
类,为要启动的容器声明 @Bean
方法。
You’ll also need to define the Container
instances that you want to start along with your application.
To do this, you need to make sure that the spring-boot-testcontainers
module has been added as a test
dependency.
Once that has been done, you can create a @TestConfiguration
class that declares @Bean
methods for the containers you want to start.
你还可以使用 @ServiceConnection
为 @Bean
方法添加注释,以创建 ConnectionDetails
bean。有关受支持技术的详细信息,请参见 the service connections 部分。
You can also annotate your @Bean
methods with @ServiceConnection
in order to create ConnectionDetails
beans.
See the service connections section for details of the supported technologies.
典型的 Testcontainers 配置看上去如下:
A typical Testcontainers configuration would look like this:
Spring Boot 自动管理 |
The lifecycle of |
你可以使用 configprop:spring.testcontainers.beans.startup[] 属性来更改容器的启动方式。默认情况下,使用 |
You can use the configprop:spring.testcontainers.beans.startup[] property to change how containers are started.
By default |
定义了测试配置后,可以使用 with(…)
方法将其附加到测试启动器:
Once you have defined your test configuration, you can use the with(…)
method to attach it to your test launcher:
现在,你可以像启动任何常规 Java main
方法应用程序一样,启动 TestMyApplication
以启动你的应用程序及运行应用程序所需的容器。
You can now launch TestMyApplication
as you would any regular Java main
method application to start your application and the containers that it needs to run.
你可以使用命令行上的 Maven goal |
You can use the Maven goal |
Contributing Dynamic Properties at Development Time
如果你想在开发期间从 Container
@Bean
方法中提供动态属性,则可以通过注入 DynamicPropertyRegistry
来实现.此操作方式类似于你可以在测试中使用的 @DynamicPropertySource
annotation.它允许你添加容器启动后即可使用的一些属性.
If you want to contribute dynamic properties at development time from your Container
@Bean
methods, you can do so by injecting a DynamicPropertyRegistry
.
This works in a similar way to the @DynamicPropertySource
annotation that you can use in your tests.
It allows you to add properties that will become available once your container has started.
典型的配置看起来如下所示:
A typical configuration would look like this:
建议在可能的情况下使用 |
Using a |
Importing Testcontainer Declaration Classes
使用 Testcontainers 时的一种常见模式是将 Container
实例声明为静态域.通常,这些域位于测试类中.它们也可以在一个父类中声明,或者在一个测试实现的接口中声明.
A common pattern when using Testcontainers is to declare Container
instances as static fields.
Often these fields are defined directly on the test class.
They can also be declared on a parent class or on an interface that the test implements.
例如,以下 MyContainers
接口声明 mongo
和 neo4j
容器:
For example, the following MyContainers
interface declares mongo
and neo4j
containers:
如果你已经拥有此方式定义的容器或者你只是喜欢这种样式,那么你可以导入这些声明类,而不是将容器定义为 @Bean
方法.为此,请向你的测试配置类添加 @ImportTestcontainers
注释:
If you already have containers defined in this way, or you just prefer this style, you can import these declaration classes rather than defining you containers as @Bean
methods.
To do so, add the @ImportTestcontainers
annotation to your test configuration class:
如果你不打算使用 service connections feature 但希望使用 |
If you don’t intend to use the service connections feature but want to use |
Using DevTools with Testcontainers at Development Time
当使用 devtools 时,你可以通过 @RestartScope
为 bean 和 bean 方法添加注释.当 devtools 重新启动应用程序时,这些 bean 将不会重新创建.这对 Testcontainer Container
bean 特别有用,因为它们保留了在应用程序重新启动的情况下.
When using devtools, you can annotate beans and bean methods with @RestartScope
.
Such beans won’t be recreated when the devtools restart the application.
This is especially useful for Testcontainer Container
beans, as they keep their state despite the application restart.
如果你正在使用 Gradle 并希望使用此功能,则需要将 spring-boot-devtools
依赖项的配置从 developmentOnly
更改为 testAndDevelopmentOnly
.在 developmentOnly
的默认范围内,bootTestRun
任务将不会拾取你的代码中的更改,因为 devtools 未处于活动状态.
If you’re using Gradle and want to use this feature, you need to change the configuration of the spring-boot-devtools
dependency from developmentOnly
to testAndDevelopmentOnly
.
With the default scope of developmentOnly
, the bootTestRun
task will not pick up changes in your code, as the devtools are not active.