Earlier this year Spring Boot 3.1.0 released a seamless integration with Testcontainers through ConnectionDetails and ServiceConnection abstractions. To learn more about it, please read Spring Boot Application Testing and Development with Testcontainers.
Spring Boot 3.1 already had support for many Testcontainers modules:
- CassandraContainer
- CouchbaseContainer
- ElasticsearchContainer
- GenericContainer using redis or openzipkin/zipkin
- JdbcDatabaseContainer
- KafkaContainer
- MongoDBContainer
- MariaDBContainer
- MSSQLServerContainer
- MySQLContainer
- Neo4jContainer
- OracleContainer
- PostgreSQLContainer
- RabbitMQContainer
- RedpandaContainer
Now, with Spring Boot version 3.2.0 out, let’s look at what’s specifically new with the Testcontainers integration.
New ServiceConnection support
Apache ActiveMQ Classic
Testcontainers doesn’t offer any specific module for ActiveMQ, but we can just use GenericContainer
, which works with any Docker image.
Using DynamicPropertySource
:
@Container static GenericContainer<?> activemq = new GenericContainer("symptoma/activemq:5.18.0").withExposedPorts(61616); @DynamicPropertySource static void properties(DynamicPropertyRegistry registry) { registry.add("spring.activemq.broker-url", () -> "tcp://%s:%d".formatted(activemq.getHost(), activemq.getMappedPort(61616))); }
Using ServiceConnection
:
@Container @ServiceConnection static GenericContainer<?> activemq = new GenericContainer("symptoma/activemq:5.18.2") .withExposedPorts(61616);
Recently, Apache ActiveMQ started releasing its own Docker images, and we can use it with Spring Boot as well, but since the current implementation expects the symptoma/activemq image name, we have to let Spring Boot know about it using the ServiceConnection’s name property.
@Container @ServiceConnection(name = "symptoma/activemq") static GenericContainer<?> activemq = new GenericContainer("apache/activemq-classic:5.18.2") .withExposedPorts(61616);
Why was apache/activemq-classic not supported from the beginning? Well, as the contributor of this feature at the time of raising the PR I was looking for the following features:
- Environment Variables for credentials
- Support in ARM
Support for credentials via environment variables was recently added. See apache/activemq#1114
Would you like to see a module for ActiveMQ? Follow testcontainers/testcontainers-java#7400
Apache Pulsar
Spring for Apache Pulsar is one of the most recent additions to the Spring portfolio, and it has been officially introduced in Spring Boot 3.2.0. Accordingly, support for ServiceConnection is provided from the beginning, and Testcontainers offers a module under the org.testcontainers:pulsar
coordinates.
Using DynamicPropertySource
:
@Container static PulsarContainer pulsar = new PulsarContainer(DockerImageName.parse("apachepulsar/pulsar:3.1.0")); @DynamicPropertySource static void pulsarProperties(DynamicPropertyRegistry registry) { registry.add("spring.pulsar.client.service-url", pulsar::getPulsarBrokerUrl); registry.add("spring.pulsar.admin.service-url", pulsar::getHttpServiceUrl); }
Using ServiceConnection
:
@ServiceConnection static PulsarContainer pulsar = new PulsarContainer(DockerImageName.parse("apachepulsar/pulsar:3.1.0"));
OpenTelemetry Collector
Similar to ActiveMQ Classic, Testcontainers doesn’t provide a module for OpenTelemetry Collector, but again GenericContainer comes to the rescue, since we can use it with any Docker image. Spring Boot supports Metrics and Tracing for OpenTelemetry.
Using DynamicPropertySource
:
@Container static final GenericContainer<?> container = new GenericContainer<>("otel/opentelemetry-collector-contrib:0.75.0") .withCommand("--config=/etc/collector-config.yml") .withCopyToContainer(MountableFile.forClasspathResource("collector-config.yml"), "/etc/collector-config.yml") .withExposedPorts(4318); @DynamicPropertySource static void pulsarProperties(DynamicPropertyRegistry registry) { registry.add("management.otlp.metrics.export.url" () -> "http://%s:%d/v1/metrics".formatted(container.getHost(), container.getMappedPort(4318); registry.add("management.otlp.tracing.endpoint" () -> "http://%s:%d/v1/traces".formatted(container.getHost(), container.getMappedPort(4318); }
Using ServiceConnection
:
@Container @ServiceConnection static final GenericContainer<?> container = new GenericContainer<>("otel/opentelemetry-collector-contrib:0.75.0") .withCommand("--config=/etc/collector-config.yml") .withCopyToContainer(MountableFile.forClasspathResource("collector-config.yml"), "/etc/collector-config.yml") .withExposedPorts(4318, 9090);
Oracle Database Free
Testcontainers’ oracle-free module is a new addition in Testcontainers for Java 1.19.2. And given that org.testcontainers.oracle.OracleContainer extends from JdbcDatabaseContainer, it is already supported by Spring Boot’s ServiceConnection for JDBC. However, R2DBC support needed some changes which were introduced in Spring Boot 3.2.0.
Using DynamicPropertySource
:
@Container static OracleContainer oracle = new OracleContainer("gvenzl/oracle-free:23.3-slim-faststart"); @DynamicPropertySource static void pulsarProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", oracle::getJdbcUrl); registry.add("spring.datasource.username", oracle::getUsername); registry.add("spring.datasource.password", oracle::getPassword); }
Using ServiceConnection
:
@Container @ServiceConnection static OracleContainer oracle = new OracleContainer("gvenzl/oracle-free:23.3-slim-faststart");
Testcontainers Beans Startup
Testcontainers allows to start containers in parallel, which can reduce the impact of the container start overhead on the overall test execution duration. Manually we can call Startables.deepStart(postgres, integresql).join();
or using Testcontainers’ JUnit Jupiter integration @Testcontainers(parallel = true)
. Those mechanisms work well when we are working with Testcontainers directly. In Spring Boot 3.1.0, we can create beans for all Testcontainers containers, see the official documentation, and now, in Spring Boot 3.2.0, a new property spring.testcontainers.beans.startup
has been added when using the spring-boot-testcontainers module. The supported values are sequential (default) and parallel.
Note: Spring Boot 3.2.0 already provides the latest and greatest Testcontainers version, 1.19.3. Remember that we can also override and upgrade it independently using the property testcontainers.version in our build file.
Spring Boot continues to add new integrations with Testcontainers, improving the developer experience, helping developers write reliable tests and ship to production with confidence. These integrations also enable developers to recreate local development environments that work seamlessly with the databases, message brokers and other external services the app depends on.