Skip to content

Test infra: switch test DB to local Docker Postgres#14

Merged
podmar merged 4 commits into
mainfrom
test/local-postgres-infra
Jun 18, 2026
Merged

Test infra: switch test DB to local Docker Postgres#14
podmar merged 4 commits into
mainfrom
test/local-postgres-infra

Conversation

@podmar

@podmar podmar commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Tests previously ran against a remote Neon database (~3 min per run). A local container cuts this significantly.

Decisions worth noting

  • Container stays running after tests finishrun-tests.sh starts the container if needed but does not stop it. Stopping on every run would negate the speed gain when running tests repeatedly. docker compose down is documented as a "done for the day" step.
  • Postgres 16 — matches Neon's default version to avoid subtle behavioural differences between local and production.
  • No docker presence check in the script — unlike the uv check, Docker's own error output is clear enough if the daemon isn't running. An explicit guard would be noise.
  • TEST_DATABASE_URL onlyDATABASE_URL (production Neon) is untouched. The safety guard in conftest.py that rejects equal URLs remains the line of defence against accidentally running tests against production.

What's next

Auth tests (test_auth.py) — register, login, bad credentials, duplicate email.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean infrastructure PR — adds local Docker Postgres for tests so you don't need a remote test database. The approach is solid and well-documented.

No security issues, no data isolation concerns (no backend code changed), and the test infrastructure setup follows good practices. The two inline comments are minor suggestions about port conflicts and wait-loop timeouts — neither is a blocker.

Comment thread docker-compose.yml
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Port conflict consideration

The hardcoded 5432:5432 mapping will conflict if the developer already has a Postgres instance running locally on the default port.

This is acceptable for a simple local dev setup, but you could consider:

  1. Using a non-standard port like "5433:5432" to avoid conflicts
  2. Documenting in README.md that port 5432 must be free
  3. Adding a check in run-tests.sh to fail early with a helpful message if the port is in use

For a portfolio project targeting simplicity, option 2 (just documenting it) is probably sufficient. The current approach is fine — just something to be aware of if you run into "port already allocated" errors.

Comment thread scripts/run-tests.sh

echo "Starting local test database..."
docker compose up -d db
until docker compose exec -T db pg_isready -U postgres -q; do sleep 1; done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice pattern: until loop with pg_isready

This is the right way to wait for Postgres — pg_isready checks if the server is actually accepting connections, not just that the container started.

The -T flag on docker compose exec is critical here: without it, Docker expects an interactive terminal and the command fails in non-interactive contexts (scripts, CI). Good catch documenting this in til.md.

One minor enhancement if you want to prevent infinite hangs: add a timeout counter:

WAIT_TIME=0
until docker compose exec -T db pg_isready -U postgres -q; do
  sleep 1
  WAIT_TIME=$((WAIT_TIME + 1))
  if [ $WAIT_TIME -gt 30 ]; then
    echo "Error: Database failed to start after 30 seconds"
    exit 1
  fi
done

But for local dev, the current infinite loop is fine — if Docker/Postgres is broken, you want to know immediately anyway.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decided to skip, easy to spot when testing locally

@claude

claude Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Summary

Critical: None — this is a clean infrastructure change with no security or data integrity issues.

Minor:

  • Port 5432 hardcoded — could conflict with existing local Postgres (acceptable tradeoff for simplicity, just document it)
  • until loop has no timeout — could hang forever if Docker fails (acceptable for local dev)

The Docker setup is well-structured, the healthcheck is correct, and the -T flag usage in the wait loop shows good understanding of Docker's interactive vs non-interactive modes.

Cost: $0.21

@podmar
podmar merged commit 549322d into main Jun 18, 2026
@podmar
podmar deleted the test/local-postgres-infra branch June 18, 2026 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant