## Description Migrate 17 Testcontainers guides from testcontainers.com into the Docker docs site, covering Java (14 guides), .NET (2 guides), and Node.js (1 guide). This follows up on PR #24450 which added the initial Go and Python guides. Each guide is converted from AsciiDoc to Hugo Markdown, split into multi-chapter stepper navigation, updated to the latest Testcontainers API, and verified with passing tests running in containers. Java guides use testcontainers-java 2.0.4 with the new 2.x Maven coordinates and package names (e.g., `testcontainers-postgresql`, `org.testcontainers.postgresql.PostgreSQLContainer`). The Quarkus guide uses Quarkus 3.22.3 with TC 1.x managed by the Quarkus BOM, since no released Quarkus version ships TC 2.x yet. ## How to test All code snippets have been verified by running each guide's source repository tests inside Docker containers with the Docker socket mounted. To re-run the verification, use the `/testcontainers-guides-migrator` skill included in this PR (`.claude/skills/testcontainers-guides-migrator/SKILL.md`). The skill's Step 6 documents the exact container commands and macOS Docker Desktop workarounds (host override, docker-java API version, etc.) needed to run each language's tests: ``` /testcontainers-guides-migrator I want you to verify all the guides in this branch. Do a full review, verifying that all code snippets compile, the code is executable, and ALL the tests pass. Run them as docker containers, never locally. ``` ## Related issues or tickets Supersedes #24450 (expanded from 2 guides to all 19) ## Reviews - [ ] Technical review - [ ] Editorial review - [ ] Product review --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6.1 KiB
title, linkTitle, description, weight
| title | linkTitle | description | weight |
|---|---|---|---|
| Write tests with Testcontainers | Write tests | Test the Quarkus REST API using Dev Services with Testcontainers, and test with services not supported by Dev Services. | 20 |
Quarkus Dev Services
Quarkus Dev Services automatically provisions unconfigured services in development and test mode. When you include an extension and don't configure it, Quarkus starts the relevant service using Testcontainers behind the scenes and wires the application to use that service.
Note
Dev Services requires a supported Docker environment.
Quarkus Dev Services supports most commonly used services like SQL databases, Kafka, RabbitMQ, Redis, and MongoDB. For more information, see the Quarkus Dev Services guide.
Write tests for the API endpoints
Test the GET /api/customers and POST /api/customers endpoints using REST
Assured. The io.rest-assured:rest-assured library was already added as a test
dependency when you generated the project.
Create CustomerResourceTest.java and annotate it with @QuarkusTest. This
bootstraps the application along with the required services using Dev Services.
Because you haven't configured datasource properties, Dev Services automatically
starts a PostgreSQL database using Testcontainers.
package com.testcontainers.demo;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.jupiter.api.Assertions.assertFalse;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.common.mapper.TypeRef;
import io.restassured.http.ContentType;
import java.util.List;
import org.junit.jupiter.api.Test;
@QuarkusTest
class CustomerResourceTest {
@Test
void shouldGetAllCustomers() {
List<Customer> customers = given().when()
.get("/api/customers")
.then()
.statusCode(200)
.extract()
.as(new TypeRef<>() {});
assertFalse(customers.isEmpty());
}
@Test
void shouldCreateCustomerSuccessfully() {
Customer customer = new Customer(null, "John", "john@gmail.com");
given().contentType(ContentType.JSON)
.body(customer)
.when()
.post("/api/customers")
.then()
.statusCode(201)
.body("name", is("John"))
.body("email", is("john@gmail.com"));
}
}
Here's what the test does:
@QuarkusTeststarts the full Quarkus application with Dev Services enabled.- Dev Services starts a PostgreSQL container using Testcontainers and configures the datasource automatically.
shouldGetAllCustomers()callsGET /api/customersand verifies that seeded data from the Flyway migration is returned.shouldCreateCustomerSuccessfully()sends aPOST /api/customersrequest and verifies the response contains the created customer data.
Customize test configuration
By default, the Quarkus test instance starts on port 8081 and uses a
postgres:14 Docker image. Customize both by adding these properties to
src/main/resources/application.properties:
quarkus.http.test-port=0
quarkus.datasource.devservices.image-name=postgres:15.2-alpine
Setting quarkus.http.test-port=0 starts the application on a random available
port, avoiding port conflicts. The devservices.image-name property lets you
pin the PostgreSQL image to a specific version that matches production.
Test with services not supported by Dev Services
Your application might use a service that Dev Services doesn't support out of
the box. In that case, use QuarkusTestResourceLifecycleManager to start the
service before the Quarkus application starts for testing.
For example, suppose the application uses CockroachDB. First, add the CockroachDB Testcontainers module dependency:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>cockroachdb</artifactId>
<scope>test</scope>
</dependency>
Create a CockroachDBTestResource that implements
QuarkusTestResourceLifecycleManager:
package com.testcontainers.demo;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import java.util.HashMap;
import java.util.Map;
import org.testcontainers.containers.CockroachContainer;
public class CockroachDBTestResource implements QuarkusTestResourceLifecycleManager {
CockroachContainer cockroachdb;
@Override
public Map<String, String> start() {
cockroachdb = new CockroachContainer("cockroachdb/cockroach:v22.2.0");
cockroachdb.start();
Map<String, String> conf = new HashMap<>();
conf.put("quarkus.datasource.jdbc.url", cockroachdb.getJdbcUrl());
conf.put("quarkus.datasource.username", cockroachdb.getUsername());
conf.put("quarkus.datasource.password", cockroachdb.getPassword());
return conf;
}
@Override
public void stop() {
cockroachdb.stop();
}
}
Use the CockroachDBTestResource with @QuarkusTestResource in a test class:
package com.testcontainers.demo;
import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertFalse;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.common.mapper.TypeRef;
import java.util.List;
import org.junit.jupiter.api.Test;
@QuarkusTest
@QuarkusTestResource(value = CockroachDBTestResource.class, restrictToAnnotatedClass = true)
class CockroachDBTest {
@Test
void shouldGetAllCustomers() {
List<Customer> customers = given().when()
.get("/api/customers")
.then()
.statusCode(200)
.extract()
.as(new TypeRef<>() {});
assertFalse(customers.isEmpty());
}
}
The restrictToAnnotatedClass = true attribute ensures the CockroachDB
container only starts when running this specific test class, rather than being
activated for all tests.