SuperAPI AI Directory

docker-testcontainers

Testing & quality

View repository

Updated 10-15 21:48

About this skill

Docker Testcontainers — Integration Test Containers

Guidance for running Docker containers in automated tests with Testcontainers.

When to Use

ALWAYS use this skill when the user mentions:

  • "testcontainers", "Testcontainer", "test containers"
  • "integration testing", "docker testing"
  • "database testing", "PostgreSQL test", "MySQL test"
  • "Java Testcontainers", "Python Testcontainers"
  • "test environment setup"

Java — Testcontainers

PostgreSQL Example

@Testcontainers
@SpringBootTest
class OrderRepositoryTest {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine")
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("test");

    @DynamicPropertySource
    static void configure(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }

    @Test
    void shouldSaveAndFindOrder() {
        Order saved = repository.save(new Order(...));
        assertThat(repository.findById(saved.getId())).isPresent();
    }
}

Redis Example

@Container
static GenericContainer<?> redis = new GenericContainer<>("redis:7-alpine")
        .withExposedPorts(6379);

// Get connection string
String redisUrl = "redis://" + redis.getHost() + ":" + redis.getMappedPort(6379);

Kafka Example

@Container
static KafkaContainer kafka = new KafkaContainer(
        DockerImageName.parse("confluentinc/cp-kafka:7.6.0"));

String bootstrapServers = kafka.getBootstrapServers();

Python — testcontainers-python

import pytest
from testcontainers.postgres import PostgresContainer
from testcontainers.redis import RedisContainer

@pytest.fixture(scope="module")
def postgres():
    with PostgresContainer("postgres:16-alpine") as pg:
        yield pg.get_connection_url()

def test_database_connection(postgres):
    import psycopg2
    conn = psycopg2.connect(postgres)
    assert conn.status == psycopg2.STATUS_READY

Container Lifecycle

// Singleton: one container for all tests
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");

// Per-test: new container for each test
@Test
void test() {
    try (var redis = new GenericContainer<>("redis:7")) {
        redis.start();
        // test...
    } // auto-closed by try-with-resources
}

CI/CD Configuration

# GitHub Actions — DinD (Docker-in-Docker)
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      docker:
        image: docker:27-dind
        options: --privileged
    steps:
      - uses: actions/checkout@v4
      - run: ./gradlew test

Workflow — Recommended Integration Process

Step 1: Add dependencies: testImplementation 'org.testcontainers:testcontainers:1.20.6' Step 2: Define containers: @Container static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine") Step 3: Inject configuration: @DynamicPropertySource Inject container connection information into Spring configuration Step 4: Write tests: @Test void shouldSaveAndFind() Normal business testing Step 5: CI acceleration: Enable withReuse(true) + GHA cache

Gotchas — Common Pitfalls

  • CI slow startup: Container images need to be pulled in CI. → Recovery: Pre-warm by adding docker pull postgres:16-alpine before test step; enable withReuse(true) in .testcontainers.properties.
  • Port conflicts in CI: Testcontainers picks random ports — no conflicts. But hardcoded ports in tests will fail. → Recovery: Always use container.getMappedPort(5432) instead of hardcoding port numbers.
  • Resource cleanup: Ryuk auto-removes containers. In CI, ensure DinD or socket access. → Recovery: If TESTCONTAINERS_RYUK_DISABLED=true, add @AfterAll cleanup; check Docker socket is mounted in CI.
  • Static vs instance containers: Static @Container fields share ONE container across the class. Instance fields create per-test containers. → Recovery: Use static for databases (shared state OK); use instance for isolation-critical tests; check @TestInstance(TestInstance.Lifecycle.PER_CLASS) for JUnit 5.

Boundary — Capability Boundaries (Applicable and Non-Applicable Scenarios)

Category Scenario Description
✅ Can do Java/Python integration testing Containerized database testing with PostgreSQL/MySQL/Redis/Kafka, etc.
✅ Can do Spring Boot testing Automatic injection with @Testcontainers + @DynamicPropertySource
✅ Can do CI integration Automatic startup/cleanup in GitHub Actions/Jenkins
⚠️ Conditional Cross-JVM reuse Requires configuration testcontainers.reuse.enable=true
⚠️ Conditional Non-Java language testing Use the corresponding Testcontainers library for each language
❌ Out of scope Manual testing/debugging Use docker-run
❌ Out of scope Production database testing Connect to production instances instead of containers
❌ Out of scope Performance/stress testing Dedicated tools (JMeter/K6)

When NOT to Use This Skill

❌ Skip ✅ Use Instead
Manual testing docker-run
Production database testing docker-storage + real instance
Mock testing Use Mockito/unittest.mock
Docker basics docker-basics

Security & Stability

  • Testcontainers use random ports — no port conflicts with running services.
  • Containers are automatically cleaned up by Ryuk after test completion.
  • Never use Testcontainers in production code — test scope only.
  • Use withReuse(true) for local development to speed up tests (container survives between runs).

📚 Official Documentation References

Documentation Address
Testcontainers Overview https://docs.docker.com/testcontainers/
Testcontainers for Java https://java.testcontainers.org/
Testcontainers Cloud https://testcontainers.com/cloud/
Spring Boot Integration https://java.testcontainers.org/modules/spring-boot/
CI Configuration https://java.testcontainers.org/supported_docker_environment/continuous_integration/

🧭 Docker Skills Journey

📍 You are here: docker-testcontainers — test containers

← Prev: docker-troubleshooting — Problem debugging → Next: docker-ai-ml — AI/ML workloads

FAQ

Q1: How do I quickly get started with this skill? A: Refer to the Quick Start section above and follow the steps.

Q2: What should I do if I encounter version incompatibility issues? A: Check dependency versions, lock them using the lock file, and refer to the Common Pitfalls section.

Q3: How can I use it in a production environment? A: Refer to the Best Practices section, ensure the configuration is correct, and implement proper monitoring and logging.

Q4: How can performance be optimized? A: Refer to the performance optimization documentation and use methods such as caching and indexing.

Q5: How can I contribute or provide feedback? A: Submit an Issue or Pull Request in the GitHub repository.

Q6: Is Chinese supported? A: Chinese documentation and Chinese comments are supported; see the domestic adaptation section for details.