Python
pytest + PostgreSQL
Unit tests without a database, integration tests against a real PostgreSQL container โ migrations applied in a setup hook, on a random port.
This guide shows:
- Container service with an
execreadiness check (pg_isready) - Random port wired into
DATABASE_URL, so parallel runs never collide - Only the integration test requests the service; unit tests stay fast
setupruns the migrations before the tests
version: 0
name: pytest-postgres
ports:
# a free port is picked per run, so parallel runs never collide
db: random
test:
name: python
sequence:
- name: install
command: pip install -r requirements-dev.txt
inputs: [requirements-dev.txt]
- name: lint
tags: [fast]
command: ruff check .
- name: checks
parallel:
- name: unit
tags: [fast]
# no database needed: pure unit tests stay fast
command: pytest tests/unit -q
- name: integration
tags: [db]
# the database is a dependency of this test only: it starts
# before the test and is stopped again afterwards
services:
postgres:
container:
image: docker.io/library/postgres:16-alpine
ports:
- "${{ ports.db }}:5432"
env:
POSTGRES_PASSWORD: testing
POSTGRES_DB: app_test
ready:
# wait until the server really accepts connections, not
# just until the container started. The probe runs inside
# the container, so it uses the image's own pg_isready and
# the container port - nothing has to be installed here
exec: pg_isready -h 127.0.0.1 -p 5432 -U postgres
interval: 500ms
timeout: 60s
env:
DATABASE_URL: postgresql://postgres:testing@127.0.0.1:${{ ports.db }}/app_test
setup:
command: alembic upgrade head
command: pytest tests/integration -q
artifacts:
- reports/**
Browse this example on GitHub โ
Copy it into your project, adjust the commands, run testfile start. Missing your
stack? Open an issue โ or
start from Getting started and let
testfile init write a first version for you.