# Backend tests Real integration tests against a real Postgres database — a dedicated `aurum_test` database created fresh, migrated, and dropped again on every run. They never touch the real `aurum` database or its data: the app's `lifespan` startup (which seeds against the real DB) is never triggered, and every route's DB dependency is overridden to point at `aurum_test` instead. ## Running The stack must already be up (`docker compose up -d`). Test dependencies aren't baked into the production image, so install them once per container lifetime, then run pytest inside the running `backend` container — it's the only place with network access to Postgres: ```bash docker compose exec backend pip install --user -r requirements-dev.txt docker compose exec backend python -m pytest -v ``` Re-run just the `python -m pytest -v` line for subsequent runs; the `pip install` only needs repeating after a container restart/rebuild. Two details that both come from the container running as an unprivileged user (`aurum`, uid 10001 — see backend/Dockerfile) rather than root: - `--user` on the install: site-packages belongs to root and isn't writable. The packages land in `/home/aurum/.local`, which isn't on `PATH`, hence `python -m pytest` instead of a bare `pytest`. - pytest prints a `PytestCacheWarning` about not being able to write `/app/.pytest_cache`. Expected — the source tree is read-only to the app user by design. Tests still pass; add `-p no:cacheprovider` to silence it. ## Adding a test - Use the `client` fixture (an `httpx.AsyncClient` wired to the app) to hit the API the same way the frontend does — prefer this over reaching into services/models directly, so tests keep verifying the actual contract. - `account_id` and `categories` fixtures give you the same default account/categories a real fresh install seeds. - Every table is truncated and reseeded before each test (see `conftest.py::_clean_database`), so tests don't need to worry about leftover state or guess at IDs from a previous test.