Skip to content

Commit 5a3e588

Browse files
committed
Create a separate section for testcontainers at development time
Closes gh-35856
1 parent e5326e1 commit 5a3e588

File tree

21 files changed

+120
-110
lines changed

21 files changed

+120
-110
lines changed

spring-boot-project/spring-boot-docs/src/docs/asciidoc/anchor-rewrite.properties

+6
Original file line numberDiff line numberDiff line change
@@ -1035,3 +1035,9 @@ deployment.installing.nix-services.script-customization=deployment.installing.in
10351035
deployment.installing.nix-services.script-customization.when-written=deployment.installing.init-d.script-customization.when-written
10361036
deployment.installing.nix-services.script-customization.when-running=deployment.installing.init-d.script-customization.when-running
10371037
deployment.installing.nix-services.script-customization.when-running.conf-file=deployment.installing.init-d.script-customization.when-running.conf-file
1038+
1039+
# gh-35856
1040+
features.testing.testcontainers.at-development-time=features.testcontainers.at-development-time
1041+
features.testing.testcontainers.at-development-time.dynamic-properties=features.testcontainers.at-development-time.dynamic-properties
1042+
features.testing.testcontainers.at-development-time.importing-container-declarations=features.testcontainers.at-development-time.importing-container-declarations
1043+
features.testing.testcontainers.at-development-time.devtools=features.testcontainers.at-development-time.devtools

spring-boot-project/spring-boot-docs/src/docs/asciidoc/features.adoc

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ include::features/testing.adoc[]
3030

3131
include::features/docker-compose.adoc[]
3232

33+
include::features/testcontainers.adoc[]
34+
3335
include::features/developing-auto-configuration.adoc[]
3436

3537
include::features/kotlin.adoc[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
[[features.testcontainers]]
2+
== Testcontainers Support
3+
As well as <<features#features.testing.testcontainers, using Testcontainers for integration testing>>, it's also possible to use them at development time.
4+
The next sections will provide more details about that.
5+
6+
7+
8+
[[features.testcontainers.at-development-time]]
9+
=== Using Testcontainers at Development Time
10+
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.
11+
Using Testcontainers in this way provides functionality similar to Docker Compose, except that your container configuration is in Java rather than YAML.
12+
13+
To use Testcontainers at development time you need to launch your application using your "`test`" classpath rather than "`main`".
14+
This will allow you to access all declared test dependencies and give you a natural place to write your test configuration.
15+
16+
To create a test launchable version of your application you should create an "`Application`" class in the `src/test` directory.
17+
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`
18+
19+
The `TestMyApplication` class can use the `SpringApplication.from(...)` method to launch the real application:
20+
21+
include::code:launch/TestMyApplication[]
22+
23+
You'll also need to define the `Container` instances that you want to start along with your application.
24+
To do this, you need to make sure that the `spring-boot-testcontainers` module has been added as a `test` dependency.
25+
Once that has been done, you can create a `@TestConfiguration` class that declares `@Bean` methods for the containers you want to start.
26+
27+
You can also annotate your `@Bean` methods with `@ServiceConnection` in order to create `ConnectionDetails` beans.
28+
See <<features#features.testing.testcontainers.service-connections, the service connections>> section for details of the supported technologies.
29+
30+
A typical Testcontainers configuration would look like this:
31+
32+
include::code:test/MyContainersConfiguration[]
33+
34+
NOTE: The lifecycle of `Container` beans is automatically managed by Spring Boot.
35+
Containers will be started and stopped automatically.
36+
37+
Once you have defined your test configuration, you can use the `with(...)` method to attach it to your test launcher:
38+
39+
include::code:test/TestMyApplication[]
40+
41+
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.
42+
43+
TIP: You can use the Maven goal `spring-boot:test-run` or the Gradle task `bootTestRun` to do this from the command line.
44+
45+
46+
47+
[[features.testcontainers.at-development-time.dynamic-properties]]
48+
==== Contributing Dynamic Properties at Development Time
49+
If you want to contribute dynamic properties at development time from your `Container` `@Bean` methods, you can do so by injecting a `DynamicPropertyRegistry`.
50+
This works in a similar way to the <<features#features.testing.testcontainers.dynamic-properties,`@DynamicPropertySource` annotation>> that you can use in your tests.
51+
It allows you to add properties that will become available once your container has started.
52+
53+
A typical configuration would look like this:
54+
55+
include::code:MyContainersConfiguration[]
56+
57+
NOTE: Using a `@ServiceConnection` is recommended whenever possible, however, dynamic properties can be a useful fallback for technologies that don't yet have `@ServiceConnection` support.
58+
59+
60+
61+
[[features.testcontainers.at-development-time.importing-container-declarations]]
62+
==== Importing Testcontainer Declaration Classes
63+
A common pattern when using Testcontainers is to declare `Container` instances as static fields.
64+
Often these fields are defined directly on the test class.
65+
They can also be declared on a parent class or on an interface that the test implements.
66+
67+
For example, the following `MyContainers` interface declares `mongo` and `neo4j` containers:
68+
69+
include::code:MyContainers[]
70+
71+
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.
72+
To do so, add the `@ImportTestcontainers` annotation to your test configuration class:
73+
74+
include::code:MyContainersConfiguration[]
75+
76+
TIP: You can use the `@ServiceConnection` annotation on `Container` fields to establish service connections.
77+
You can also add <<features#features.testing.testcontainers.dynamic-properties,`@DynamicPropertySource` annotated methods>> to your declaration class.
78+
79+
80+
81+
[[features.testcontainers.at-development-time.devtools]]
82+
==== Using DevTools with Testcontainers at Development Time
83+
When using devtools, you can annotate beans and bean methods with `@RestartScope`.
84+
Such beans won't be recreated when the devtools restart the application.
85+
This is especially useful for Testcontainer `Container` beans, as they keep their state despite the application restart.
86+
87+
include::code:MyContainersConfiguration[]
88+
89+
WARNING: 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 `testImplementation`.
90+
With the default scope of `developmentOnly`, the `bootTestRun` task will not pick up changes in your code, as the devtools are not active.

spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc

-87
Original file line numberDiff line numberDiff line change
@@ -1036,93 +1036,6 @@ The above configuration allows Neo4j-related beans in the application to communi
10361036

10371037

10381038

1039-
[[features.testing.testcontainers.at-development-time]]
1040-
==== Using Testcontainers at Development Time
1041-
As well as using Testcontainers for integration testing, it's also possible to use them at development time.
1042-
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.
1043-
Using Testcontainers in this way provides functionality similar to Docker Compose, except that your container configuration is in Java rather than YAML.
1044-
1045-
To use Testcontainers at development time you need to launch your application using your "`test`" classpath rather than "`main`".
1046-
This will allow you to access all declared test dependencies and give you a natural place to write your test configuration.
1047-
1048-
To create a test launchable version of your application you should create an "`Application`" class in the `src/test` directory.
1049-
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`
1050-
1051-
The `TestMyApplication` class can use the `SpringApplication.from(...)` method to launch the real application:
1052-
1053-
include::code:launch/TestMyApplication[]
1054-
1055-
You'll also need to define the `Container` instances that you want to start along with your application.
1056-
To do this, you need to make sure that the `spring-boot-testcontainers` module has been added as a `test` dependency.
1057-
Once that has been done, you can create a `@TestConfiguration` class that declares `@Bean` methods for the containers you want to start.
1058-
1059-
You can also annotate your `@Bean` methods with `@ServiceConnection` in order to create `ConnectionDetails` beans.
1060-
See <<features#features.testing.testcontainers.service-connections, the service connections>> section above for details of the supported technologies.
1061-
1062-
A typical Testcontainers configuration would look like this:
1063-
1064-
include::code:test/MyContainersConfiguration[]
1065-
1066-
NOTE: The lifecycle of `Container` beans is automatically managed by Spring Boot.
1067-
Containers will be started and stopped automatically.
1068-
1069-
Once you have defined your test configuration, you can use the `with(...)` method to attach it to your test launcher:
1070-
1071-
include::code:test/TestMyApplication[]
1072-
1073-
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.
1074-
1075-
TIP: You can use the Maven goal `spring-boot:test-run` or the Gradle task `bootTestRun` to do this from the command line.
1076-
1077-
1078-
1079-
[[features.testing.testcontainers.at-development-time.dynamic-properties]]
1080-
===== Contributing Dynamic Properties at Development Time
1081-
If you want to contribute dynamic properties at development time from your `Container` `@Bean` methods, you can do so by injecting a `DynamicPropertyRegistry`.
1082-
This works in a similar way to the <<features#features.testing.testcontainers.dynamic-properties,`@DynamicPropertySource` annotation>> that you can use in your tests.
1083-
It allows you to add properties that will become available once your container has started.
1084-
1085-
A typical configuration would look like this:
1086-
1087-
include::code:MyContainersConfiguration[]
1088-
1089-
NOTE: Using a `@ServiceConnection` is recommended whenever possible, however, dynamic properties can be a useful fallback for technologies that don't yet have `@ServiceConnection` support.
1090-
1091-
1092-
1093-
[[features.testing.testcontainers.at-development-time.importing-container-declarations]]
1094-
===== Importing Testcontainer Declaration Classes
1095-
A common pattern when using Testcontainers is to declare `Container` instances as static fields.
1096-
Often these fields are defined directly on the test class.
1097-
They can also be declared on a parent class or on an interface that the test implements.
1098-
1099-
For example, the following `MyContainers` interface declares `mongo` and `neo4j` containers:
1100-
1101-
include::code:MyContainers[]
1102-
1103-
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.
1104-
To do so, add the `@ImportTestcontainers` annotation to your test configuration class:
1105-
1106-
include::code:MyContainersConfiguration[]
1107-
1108-
TIP: You can use the `@ServiceConnection` annotation on `Container` fields to establish service connections.
1109-
You can also add <<features#features.testing.testcontainers.dynamic-properties,`@DynamicPropertySource` annotated methods>> to your declaration class.
1110-
1111-
1112-
1113-
[[features.testing.testcontainers.at-development-time.devtools]]
1114-
===== Using DevTools with Testcontainers at Development Time
1115-
When using devtools, you can annotate beans and bean methods with `@RestartScope`.
1116-
Such beans won't be recreated when the devtools restart the application.
1117-
This is especially useful for Testcontainer `Container` beans, as they keep their state despite the application restart.
1118-
1119-
include::code:MyContainersConfiguration[]
1120-
1121-
WARNING: 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 `testImplementation`.
1122-
With the default scope of `developmentOnly`, the `bootTestRun` task will not pick up changes in your code, as the devtools are not active.
1123-
1124-
1125-
11261039
[[features.testing.utilities]]
11271040
=== Test Utilities
11281041
A few test utility classes that are generally useful when testing your application are packaged as part of `spring-boot`.
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.devtools;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.devtools;
1818

1919
import org.testcontainers.containers.MongoDBContainer;
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.dynamicproperties;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.dynamicproperties;
1818

1919
import org.testcontainers.containers.MongoDBContainer;
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.importingcontainerdeclarations;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.importingcontainerdeclarations;
1818

1919
import org.testcontainers.containers.MongoDBContainer;
2020
import org.testcontainers.containers.Neo4jContainer;
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.importingcontainerdeclarations;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.importingcontainerdeclarations;
1818

1919
import org.springframework.boot.test.context.TestConfiguration;
2020
import org.springframework.boot.testcontainers.context.ImportTestcontainers;
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.launch;
1818

1919
public class MyApplication {
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.launch;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.launch;
1818

1919
import org.springframework.boot.SpringApplication;
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.launch;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.test;
1818

1919
public class MyApplication {
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.test;
1818

1919
import org.testcontainers.containers.Neo4jContainer;
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test;
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.test;
1818

1919
import org.springframework.boot.SpringApplication;
2020

Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.devtools
16+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.devtools
1717

1818
import org.springframework.boot.devtools.restart.RestartScope
1919
import org.springframework.boot.test.context.TestConfiguration
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.dynamicproperties
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.dynamicproperties
1818

1919
import org.springframework.boot.test.context.TestConfiguration
2020
import org.springframework.context.annotation.Bean;
@@ -32,4 +32,4 @@ class MyContainersConfiguration {
3232
return container
3333
}
3434

35-
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.importingcontainerdeclarations
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.importingcontainerdeclarations
1818

1919
import org.springframework.boot.test.context.TestConfiguration
2020
import org.springframework.boot.testcontainers.context.ImportTestcontainers
@@ -23,4 +23,4 @@ import org.springframework.boot.testcontainers.context.ImportTestcontainers
2323
@ImportTestcontainers(MyContainers::class)
2424
class MyContainersConfiguration {
2525

26-
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.launch
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.launch
1818

1919
import org.springframework.boot.autoconfigure.SpringBootApplication
2020
import org.springframework.boot.docs.features.springapplication.MyApplication
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.launch
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.launch
1818

1919
import org.springframework.boot.fromApplication
2020

Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.test
1818

1919
import org.springframework.boot.autoconfigure.SpringBootApplication
2020
import org.springframework.boot.docs.features.springapplication.MyApplication
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test
18-
19-
import org.testcontainers.containers.Neo4jContainer
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.test
2018

2119
import org.springframework.boot.test.context.TestConfiguration
2220
import org.springframework.boot.testcontainers.service.connection.ServiceConnection
23-
import org.springframework.context.annotation.Bean;
21+
import org.springframework.context.annotation.Bean
22+
import org.testcontainers.containers.Neo4jContainer
2423

2524
@TestConfiguration(proxyBeanMethods = false)
2625
class MyContainersConfiguration {
@@ -31,4 +30,4 @@ class MyContainersConfiguration {
3130
return Neo4jContainer("neo4j:5")
3231
}
3332

34-
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test
17+
package org.springframework.boot.docs.features.testcontainers.atdevelopmenttime.test
1818

1919
import org.springframework.boot.fromApplication
2020
import org.springframework.boot.with

0 commit comments

Comments
 (0)