If you develop services using Spring Boot and maybe Spring Cloud and you do medium sized tests during build process, then this set of Spring Boot auto-configurations might be handy. By adding module into classpath, you will get stateful service, like Couchbase or Kafka, auto-started and available for connection from your application service w/o wiring any additional code. Docker and TestContainers are used to bootstrap stateful service using Spring Cloud bootstrap phase. Usage of Spring Cloud in your production code is optional, but you will need it in tests. See How to use below.
Spring Boot | Test Containers Spring Boot |
---|---|
2.5.X, 2.6.X, 2.7.X |
2.X.X |
3.0.X, 3.1.X |
3.0.X |
3.2.X |
3.1.X |
-
Install Docker on your machine
-
Make sure you have Spring Boot and Spring Cloud in classpath of your tests. In case if you need to pick version.
pom.xml<project> ... <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap --> <version>[pick version]</version> </dependency> ... </project>
Notetestcontainers-spring-boot
project migrated to Spring Boot 2.4 in 2.0.0 version. Please note, that in order to use this project with Spring Boot 2.4, you need to usespring-cloud-starter-bootstrap
dependency. For earlier Spring Boot (prior to 2.4) users — you need to usespring-cloud-starter
dependency instead. -
If you do not use Spring Cloud - make it work for tests only:
pom.xml<project> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter --> <version>[pick version]</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap --> <version>[pick version]</version> <scope>test</scope> </dependency> ... </project>
-
Add data service library:
pom.xml<project> ... <dependency> <groupId>com.playtika.testcontainers</groupId> <artifactId>embedded-kafka</artifactId> <!-- https://mvnrepository.com/artifact/com.playtika.testcontainers/ --> <version>[pick version]</version> <scope>test</scope> </dependency> ... </project>
-
Use produced properties in your configuration.
Example:
/src/test/resources/application.propertiesspring.kafka.bootstrap-servers=${embedded.kafka.brokerList}
/src/test/resources/bootstrap.propertiesembedded.kafka.topicsToCreate=some_topic
embedded.containers.forceShutdown=true #default is false
Note
|
Otherwise, it will be shutdown with delay, see https://github.com/testcontainers/moby-ryuk |
embedded.containers.enabled=true #default is true
Note
|
If you setup, for example embedded.kafka.enabled + embedded.containers.enabled, result will be same as using AND between two booleans. |
Note
|
embedded.kafka.enabled=false will cause DockerNotPresentException if you don’t have docker installed. But embedded.containers.enabled=false won’t cause any exceptions in this case. |
Setting1 | Setting2 | Outcome |
---|---|---|
embedded.containers.enabled=false |
embedded.memsql.enabled=true |
Memsql will not start |
embedded.containers.enabled=true |
embedded.memsql.enabled=false |
Memsql will not start |
embedded.containers.enabled=true |
embedded.memsql.enabled=true |
Memsql will start |
embedded.containers.enabled is missing |
embedded.memsql.enabled is missing |
Memsql will start |
Setting name | Default value | Description |
---|---|---|
embedded.{module-name}.dockerImage |
Depends on module |
Full Docker image name for container setup. Most of the modules have default value already setup. |
embedded.{module-name}.dockerImageVersion |
N/A |
Use this property if you want to override only Docker image’s version. |
embedded.{module-name}.waitTimeoutInSeconds |
60 |
Waiting time for a container to start in seconds |
embedded.{module-name}.enabled |
true |
Enables a container to be started on startup |
embedded.{module-name}.reuseContainer |
false |
Enables a reuse container Testcontainers feature. For more info please refer to: testcontainers/testcontainers-java#2555 and testcontainers/testcontainers-java#1781. |
embedded.{module-name}.command |
null |
List of keywords which combines into command for container startup. Some modules ship container’s commands by default, so resetting this value may lead to incorrect work of container. |
embedded.{module-name}.attachContainerLog |
false |
Attach embedded container output log. |
embedded.{module-name}.env |
null |
key-value map of additional environment variables. Where key is name of variable and value is actual value of it. |
embedded.{module-name}.label |
null |
key-value map of additional labels to the container. Where key is name of label and value is actual value of label. |
embedded.{module-name}.filesToInclude |
empty list |
List of files to include objects. Each object should have two parameters:
Example: embedded.redis.filesToInclude:
classpathResource: "/my_local_file.txt"
containerPath: "/etc/path_in_container.txt" |
embedded.{module-name}.mountVolumes |
empty list |
List of mount volumes to persist between container restarts. Each object should have three parameters:
Example: embedded.postgresql.mountVolumes:
hostPath: "pgdata"
containerPath: "/var/lib/postgresql/data"
mode: READ_WRITE |
embedded.{module-name}.capabilities |
empty list. |
The Linux capabilities that should be enabled. You can disable all capabilities by providing empty value for this property.
See: https://man7.org/linux/man-pages/man7/capabilities.7.html.
Available values can be taken from |
embedded.{module-name}.tmpFs.mounts |
empty list |
A list of container directories which should be replaced by tmpfs mounts, and their corresponding mount options. Check TmpFs mount docs. For example, for MariaDb: embedded:
mariadb:
tmp-fs:
mounts:
- folder: /var/lib/mysql
options: rw |
-
You need to fork project and create branch from
develop
-
You do not need to update project version in
pom.xml
files, this will be done by release job -
Once finished - create pull request to
develop
from your fork, pass review and wait for merge -
On release, ci job will update to next release version + publish artifacts to the Maven Central
-
Naming/formatting patterns match existing code
-
Test for success scenario
-
Test for negative scenario (autoconfiguration is disabled via properties). How to test autoconfiguration
-
Add new module to
testcontainers-spring-boot-bom
-
Module provides documentation in
README.adoc
and this documentation is included in parentREADME.adoc
(see an example in already existing modules). Documentation should include:-
maven module declaration
-
consumed properties
-
produced properties
-
notes (if applicable)
-
example of usage
-
-
Release is done per each major change, critical bug
-
Release can be done by contributor request
-
Contacts to start release: