Files
docker-docs/content/guides/testcontainers-go-getting-started/write-tests.md
Manuel de la Peña 36d384d2da docs(guides): add two testcontainers intro guides (go and python) (#24450)
## Description

Migrate the first two Testcontainers getting-started guides from
[testcontainers.com/guides](https://testcontainers.com/guides/) into the
Docker docs site:

- **Getting started with Testcontainers for Go** — multi-page guide with
4 chapters (create project, write tests, test suites, run tests). Code
updated to testcontainers-go v0.41.0 API (`postgres.Run()`,
`CleanupContainer`, `BasicWaitStrategies()`).
- **Getting started with Testcontainers for Python** — multi-page guide
with 3 chapters (create project, write tests, run tests). Code updated
to testcontainers-python 4.14.2 (fixed `get_exposed_port()` returning
`int`).

Each guide appears as its own entry in the `/guides/` listing with
proper language and tag filters (`testing-with-docker`). Chapters render
with stepper navigation in the sidebar.

Also adds:
- A `testing-with-docker` tag to `data/tags.yaml`
- A Claude skill
(`.claude/skills/testcontainers-guides-migrator/SKILL.md`) that
documents the repeatable migration process for the remaining 19 guides
- Links from `content/manuals/testcontainers.md` to the new guides
- Vale vocabulary entries for `pgx`, `Micronaut`, `psycopg`, `pytest`

All guide code was compiled and tests verified passing in containers
with Docker socket mounted.

## Related issues or tickets

No related issues found.

## Reviews

- [ ] Technical review
- [ ] Editorial review
- [ ] Product review
2026-03-23 13:58:19 +00:00

3.5 KiB

title, linkTitle, description, weight
title linkTitle description weight
Write tests with Testcontainers Write tests Write your first integration test using testcontainers-go and PostgreSQL. 20

You have the Repository implementation ready, but for testing you need a PostgreSQL database. You can use testcontainers-go to spin up a Postgres database in a Docker container and run your tests against that database.

Set up the test database

In real applications you might use a database migration tool, but for this guide, use a script to initialize the database.

Create a testdata/init-db.sql file to create the CUSTOMERS table and insert sample data:

CREATE TABLE IF NOT EXISTS customers (id serial, name varchar(255), email varchar(255));

INSERT INTO customers(name, email) VALUES ('John', 'john@gmail.com');

Understand the testcontainers-go API

The testcontainers-go library provides the generic Container abstraction that can run any containerized service. To further simplify, testcontainers-go provides technology-specific modules that reduce boilerplate and provide a functional options pattern to construct the container instance.

For example, PostgresContainer provides WithDatabase(), WithUsername(), WithPassword(), and other functions to set various properties of Postgres containers.

Write the test

Create the customer/repo_test.go file and implement the test:

package customer

import (
	"context"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/postgres"
)

func TestCustomerRepository(t *testing.T) {
	ctx := context.Background()

	ctr, err := postgres.Run(ctx,
		"postgres:16-alpine",
		postgres.WithInitScripts(filepath.Join("..", "testdata", "init-db.sql")),
		postgres.WithDatabase("test-db"),
		postgres.WithUsername("postgres"),
		postgres.WithPassword("postgres"),
		postgres.BasicWaitStrategies(),
	)
	testcontainers.CleanupContainer(t, ctr)
	require.NoError(t, err)

	connStr, err := ctr.ConnectionString(ctx, "sslmode=disable")
	require.NoError(t, err)

	customerRepo, err := NewRepository(ctx, connStr)
	require.NoError(t, err)

	c, err := customerRepo.CreateCustomer(ctx, Customer{
		Name:  "Henry",
		Email: "henry@gmail.com",
	})
	assert.NoError(t, err)
	assert.NotNil(t, c)

	customer, err := customerRepo.GetCustomerByEmail(ctx, "henry@gmail.com")
	assert.NoError(t, err)
	assert.NotNil(t, customer)
	assert.Equal(t, "Henry", customer.Name)
	assert.Equal(t, "henry@gmail.com", customer.Email)
}

Here's what the test does:

  • Calls postgres.Run() with the postgres:16-alpine Docker image as the first argument. This is the v0.41.0 API — the image is a required positional parameter instead of an option.
  • Configures initialization scripts using WithInitScripts(...) so that the CUSTOMERS table is created and sample data is inserted after the database starts.
  • Uses postgres.BasicWaitStrategies() which combines waiting for the Postgres log message and for the port to be ready. This replaces manual wait strategy configuration.
  • Calls testcontainers.CleanupContainer(t, ctr) right after postgres.Run(). This registers automatic cleanup with the test framework, replacing the manual t.Cleanup and Terminate pattern.
  • Obtains the database ConnectionString from the container and initializes a Repository.
  • Creates a customer with the email henry@gmail.com and verifies that the customer exists in the database.