Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5102972
chore: improve skill to validate guides on migration
mdelapenya Mar 20, 2026
412a7d2
chore(guides): migrate java guide with the skill
mdelapenya Mar 20, 2026
cccc47c
feat(guides): add testcontainers Node.js getting-started guide
mdelapenya Mar 20, 2026
8e9de32
feat(guides): add testcontainers .NET getting-started guide
mdelapenya Mar 20, 2026
ea2995f
feat(guides): add testcontainers Java Spring Boot REST API guide
mdelapenya Mar 20, 2026
862b166
feat(guides): add testcontainers Java lifecycle management guide
mdelapenya Mar 21, 2026
bf9e950
feat(guides): add testcontainers Java replace-h2 guide
mdelapenya Mar 21, 2026
c0c3dce
feat(guides): add testcontainers Java service configuration guide
mdelapenya Mar 21, 2026
92ed592
feat(guides): add testcontainers Java Spring Boot Kafka guide
mdelapenya Mar 21, 2026
e45f4ea
feat(guides): add testcontainers Java MockServer guide
mdelapenya Mar 21, 2026
941aeaa
feat(guides): add testcontainers Java AWS LocalStack guide
mdelapenya Mar 21, 2026
56c06b8
chore: update cross-references and vale vocabulary
mdelapenya Mar 21, 2026
b144052
feat(guides): add testcontainers .NET ASP.NET Core guide
mdelapenya Mar 21, 2026
847339b
feat(guides): add testcontainers Java WireMock guide
mdelapenya Mar 21, 2026
42aa60f
feat(guides): add testcontainers Java Micronaut WireMock guide
mdelapenya Mar 21, 2026
1c2e74c
feat(guides): add testcontainers Java Keycloak Spring Boot guide
mdelapenya Mar 21, 2026
302a344
feat(guides): add testcontainers Java Quarkus guide
mdelapenya Mar 21, 2026
6e266b8
feat(guides): add testcontainers Java Micronaut Kafka guide
mdelapenya Mar 21, 2026
5cab026
feat(guides): add testcontainers Java jOOQ/Flyway guide
mdelapenya Mar 21, 2026
47c7606
chore: add links to remaining migrated guides
mdelapenya Mar 21, 2026
284ee5b
chore: move Quickstart section above Guides in testcontainers page
mdelapenya Mar 21, 2026
3e1c30c
chore: version fixes
mdelapenya Mar 24, 2026
8b8c606
chore: bump testcontainers-java to the most recent versions
mdelapenya Mar 24, 2026
35c29ed
fix: update references and vale
mdelapenya Mar 24, 2026
21c03a3
chore: add to vale
mdelapenya Mar 24, 2026
23ecd19
chore: update skill with language ergonomics
mdelapenya Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 96 additions & 10 deletions .claude/skills/testcontainers-guides-migrator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ These are the 21 guides from testcontainers.com/guides/ and their source repos:
| 20 | Getting started for Python | tc-guide-getting-started-with-testcontainers-for-python | python | getting-started |
| 21 | Keycloak with Spring Boot | tc-guide-securing-spring-boot-microservice-using-keycloak-and-testcontainers | java | keycloak-spring-boot |

Already migrated: **#13 (Go getting-started)**, **#20 (Python getting-started)**
Already migrated: **#2 (Java getting-started)**, **#13 (Go getting-started)**, **#20 (Python getting-started)**

## Step 0: Pre-flight

Expand Down Expand Up @@ -137,8 +137,9 @@ For each language, check the cloned repo's existing code, then update to the lat
- No `TearDownSuite()` needed if `CleanupContainer` is registered in the helper
- Go version prerequisite: 1.25+

**Java** (testcontainers-java):
- Check the latest BOM version at https://java.testcontainers.org/
**Java** (testcontainers-java 2.0.4):
- Artifacts renamed in 2.x: `org.testcontainers:postgresql` → `org.testcontainers:testcontainers-postgresql`
- Check the latest version at https://java.testcontainers.org/
- Use `@Testcontainers` and `@Container` annotations for JUnit 5 lifecycle
- Prefer module-specific containers (e.g. `PostgreSQLContainer`) over `GenericContainer`
- Use `@DynamicPropertySource` for Spring Boot integration
Expand Down Expand Up @@ -246,17 +247,90 @@ If compilation fails, fix the code and update the guide markdown to match.

### 6d: Run tests in a container with Docker socket mounted

Run tests in the same kind of container, but **mount the Docker socket** so Testcontainers can create sibling containers:
Run tests in the same kind of container, but **mount the Docker socket** so Testcontainers can create sibling containers.

#### macOS Docker Desktop workarounds

When running on macOS with Docker Desktop, these environment variables and flags are **required**:

- **`TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal`** — On macOS, containers can't reach sibling containers via the Docker bridge IP (`172.17.0.x`). This tells Testcontainers (including Ryuk) to connect via `host.docker.internal` instead. **Do NOT disable Ryuk** — it is a core Testcontainers feature and the guides must demonstrate proper usage.
- **`docker-java.properties`** with `api.version=1.47` — Docker Desktop's minimum API version is 1.44, but docker-java defaults to 1.24. Create this file in the project root and mount it to `/root/.docker-java.properties` inside Java containers.
- **`-Dspotless.check.skip=true`** — The Spotless Maven plugin in the source repos is incompatible with JDK 21. Skip it since it's a code formatter, not part of the test.
- **`-Dmicronaut.test.resources.enabled=false`** — Micronaut's Test Resources service starts a separate process that can't connect to Docker from inside a container. The guide tests use Testcontainers directly, not Test Resources. Only needed for Micronaut guides.
#### Java guide test command

```bash
# Create docker-java.properties in the project root
echo "api.version=1.47" > <tmpdir>/{REPO_NAME}/docker-java.properties

docker run --rm \
-v "<tmpdir>/{REPO_NAME}":/app \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "<tmpdir>/{REPO_NAME}/docker-java.properties":/root/.docker-java.properties \
-e DOCKER_HOST=unix:///var/run/docker.sock \
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
-w /app \
maven:3.9-eclipse-temurin-21 \
mvn -B test -Dspotless.check.skip=true -Dspotless.apply.skip=true
```

For Quarkus guides, use `maven:3.9-eclipse-temurin-17` instead (Quarkus 3.22.3 compiles for Java 17).

#### Go guide test command

```bash
docker run --rm \
-v "<tmpdir>/{REPO_NAME}":/app \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DOCKER_HOST=unix:///var/run/docker.sock \
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
-w /app \
golang:1.25-alpine \
sh -c "apk add --no-cache gcc musl-dev && go test -v -count=1 ./..."
```

#### Python guide test command

```bash
docker run --rm \
-v "<tmpdir>/{REPO_NAME}":/app \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /app <language-image> \
sh -c "<test command>"
-e DOCKER_HOST=unix:///var/run/docker.sock \
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
-w /app \
python:3.13-slim \
sh -c "pip install -r requirements.txt && python -m pytest"
```

The key is `-v /var/run/docker.sock:/var/run/docker.sock` — this lets Testcontainers inside the container talk to the host's Docker daemon and create sibling containers.
#### .NET guide test command

```bash
docker run --rm \
-v "<tmpdir>/{REPO_NAME}":/app \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DOCKER_HOST=unix:///var/run/docker.sock \
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
-w /app \
mcr.microsoft.com/dotnet/sdk:9.0 \
dotnet test
```

#### Node.js guide test command

```bash
docker run --rm \
-v "<tmpdir>/{REPO_NAME}":/app \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DOCKER_HOST=unix:///var/run/docker.sock \
-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal \
-w /app \
node:22-alpine \
sh -c "npm install && npm test"
```

#### Important: run tests sequentially

Run guide tests **one at a time**. Running multiple concurrent DinD or sibling-container tests can overwhelm Docker Desktop's containerd store and cause `meta.db: input/output error` corruption, requiring a Docker Desktop restart.

### 6e: Fix until green

Expand All @@ -274,11 +348,23 @@ If any test fails, debug and fix the code in both the temporary project AND the

## Step 8: Validate

**IMPORTANT**: Run ALL validation locally before committing. Vale checks run on CI and will block the PR if they fail — fixing after push wastes CI cycles and review time.

1. `npx prettier --write content/guides/testcontainers-{LANG}-{GUIDE_ID}/`
2. `npx prettier --write content/manuals/testcontainers.md`
3. `docker buildx bake lint` — must pass
4. `docker buildx bake vale` — check `tmp/vale.out` for errors in new files
- Spelling errors for tech terms: add to `_vale/config/vocabularies/Docker/accept.txt`
3. `docker buildx bake lint` — must pass with no errors
4. `docker buildx bake vale` — then check for errors in the new files:
```bash
grep -A2 "testcontainers-{LANG}-{GUIDE_ID}" tmp/vale.out
```
Fix ALL errors before proceeding. Common issues:
- **Vale.Spelling**: tech terms (library names, tools) not in the dictionary → add to `_vale/config/vocabularies/Docker/accept.txt` (alphabetical order)
- **Vale.Terms**: wrong casing (e.g. "python" → "Python") → fix in the markdown. Watch for package names like `testcontainers-python` triggering false positives — rephrase to "Testcontainers for Python" in prose.
- **Docker.Avoid**: hedge words like "very", "simply" → reword
- **Docker.We**: first-person plural → rewrite to "you" or imperative
- Info-level suggestions (e.g. "VS Code" → "versus") are not blocking but review them

Re-run `docker buildx bake vale` after fixes until no errors remain in the new files.
5. Verify in local dev server (`HUGO_PORT=1314 docker compose watch`):
- Guide appears when filtering by its language
- Guide appears when filtering by `Testing with Docker` tag
Expand Down
19 changes: 18 additions & 1 deletion _vale/config/vocabularies/Docker/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exfiltration
sandboxing
Adreno
Aleksandrov
Awaitility
Amazon
Anchore
Apple
Expand Down Expand Up @@ -36,6 +37,7 @@ Chrome DevTools
CI
CI/CD
Citrix
classpath
cli
CLI
CloudFront
Expand All @@ -48,13 +50,14 @@ CouchDB
Crowdstrike
[Cc]ybersecurity
datacenter
datasource
Datadog
Ddosify
Debootstrap
denylist
deprovisioning
deserialization
deserialize
deserialize[d]?
Dev
Dev Environments?
Dex
Expand Down Expand Up @@ -96,13 +99,16 @@ Git
GitHub
GitHub Actions
Google
Gradle
Grafana
Gravatar
gRPC
Groq
Grype
HyperKit
inferencing
initializer
Initializr
inotify
Intel
Intune
Expand All @@ -117,6 +123,7 @@ JetBrains
JFrog
JUnit
Kata
Keycloak
Kerberos
Kiro
Kitematic
Expand All @@ -129,7 +136,9 @@ Laradock
Laravel
libseccomp
Linux
Liquibase
LinuxKit
logback
Loggly
Logstash
lookup
Expand All @@ -138,15 +147,18 @@ macOS
macvlan
Mail(chimp|gun)
mfsymlinks
Micronaut
Microsoft
minikube
misconfiguration
monorepos?
musl
MySQL
nameserver
namespaced?
namespacing
Neovim
Npgsql
netfilter
netlabel
netlink
Expand Down Expand Up @@ -222,14 +234,18 @@ Traefik
Trivy
Trixie
Turtlesim
typesafe
Ubuntu
ufw
umask
uncaptured
Uncaptured
unconfigured
undeterminable
Unix
unmarshalling
unmanaged
upsert
Visual Studio Code
VMware
vpnkit
Expand All @@ -244,6 +260,7 @@ WireMock
workdir
WORKDIR
Xdebug
xUnit
XQuartz
youki
Yubikey
Expand Down
36 changes: 36 additions & 0 deletions content/guides/testcontainers-dotnet-aspnet-core/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: Testing an ASP.NET Core web app with Testcontainers
linkTitle: ASP.NET Core testing
description: Learn how to use Testcontainers for .NET to replace SQLite with a real Microsoft SQL Server in ASP.NET Core integration tests.
keywords: testcontainers, dotnet, csharp, testing, mssql, asp.net core, integration testing, entity framework
summary: |
Learn how to test an ASP.NET Core web app using Testcontainers for .NET
with a real Microsoft SQL Server instance instead of SQLite.
toc_min: 1
toc_max: 2
tags: [testing-with-docker]
languages: [c-sharp]
params:
time: 25 minutes
---

<!-- Source: https://github.com/testcontainers/tc-guide-testing-aspnet-core -->

In this guide, you'll learn how to:

- Use Testcontainers for .NET to spin up a Microsoft SQL Server container for integration tests
- Replace SQLite with a production-like database provider in ASP.NET Core tests
- Customize `WebApplicationFactory` to configure test dependencies with Testcontainers
- Manage container lifecycle with xUnit's `IAsyncLifetime`

## Prerequisites

- .NET 8.0+ SDK
- A code editor or IDE (Visual Studio, VS Code, Rider)

Check warning on line 29 in content/guides/testcontainers-dotnet-aspnet-core/_index.md

View workflow job for this annotation

GitHub Actions / validate (vale)

[vale] reported by reviewdog 🐶 [Docker.RecommendedWords] Consider using 'versus' instead of 'VS' Raw Output: {"message": "[Docker.RecommendedWords] Consider using 'versus' instead of 'VS'", "location": {"path": "content/guides/testcontainers-dotnet-aspnet-core/_index.md", "range": {"start": {"line": 29, "column": 40}}}, "severity": "INFO"}
- A Docker environment supported by Testcontainers. For details, see the
[Testcontainers .NET system requirements](https://dotnet.testcontainers.org/supported_docker_environment/).

> [!NOTE]
> If you're new to Testcontainers, visit the
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
> Testcontainers and the benefits of using it.
Loading