Files
mivanchenko 3a20cb5d2b CI: run backoffice test suite on push/PR, document local test setup
Adds .gitea/workflows/test-backoffice.yml (paths-filtered to
backoffice/app/** and backoffice/db/**, self-hosted homelab runner,
plain git clone matching deploy-backoffice.yml's conventions) so a
regression no longer needs a human to notice it.

The psycopg[binary]==3.2.1 pin turned out to be correct, not stale: it
only ships wheels through cp312, so it resolves cleanly under the
project's python:3.12-slim target but not under newer interpreters.
Documented in requirements.txt and docs/agents/testing.md, along with
the fact that the suite spins up its own throwaway postgres:16-alpine
container (tests/conftest.py) with no manual DB setup required.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 17:34:43 +02:00

3.1 KiB
Raw Permalink Blame History

Testing: backoffice (smb-crm)

Running the suite locally

python3.12 -m venv .venv          # must be 3.12 — see "psycopg pin" below
.venv/bin/pip install -r backoffice/app/requirements-dev.txt
cd backoffice/app && ../../.venv/bin/python -m pytest tests/ -q

No python3.12 on your machine? Run it in a container instead — this is what CI does (see .gitea/workflows/test-backoffice.yml):

docker run --rm --network host -v "$PWD":/repo -v /var/run/docker.sock:/var/run/docker.sock \
  -w /repo -e HOME=/tmp python:3.12-slim bash -c '
    apt-get update -qq && apt-get install -y -qq docker.io >/dev/null
    python3 -m venv .venv && .venv/bin/pip install -q -r backoffice/app/requirements-dev.txt
    .venv/bin/python -m pytest backoffice/app/tests -q'

--network host matters: tests/conftest.py runs docker run -p 127.0.0.1:<port>:5432 as a sibling container via the mounted socket, and the test process needs to see that published port in the same network namespace.

Docker is the only prerequisite

backoffice/app/tests/conftest.py starts its own throwaway postgres:16-alpine container at collection time (a docker run in module scope, bound to a random free local port), applies backoffice/db/init.sql against it, and stops it via atexit when the process exits. There is:

  • no DATABASE_URL to set by hand — the fixture sets os.environ["DATABASE_URL"] itself
  • no shared/persistent test database to seed, migrate, or worry about polluting between runs
  • nothing to tear down manually — a crashed run leaves an orphaned smb-booking-test-db-* container behind (docker ps -a | grep smb-booking-test-db to find and docker rm -f it), but the container name is randomized per run so it never collides with a live one.

Per module docstring, this is deliberate (issue #14's testing decision): real Postgres, no mocking, so the booking EXCLUDE constraint and tenancy filters get exercised for real.

The psycopg[binary]==3.2.1 pin: why it can fail to install, and the fix

backoffice/app/requirements.txt pins psycopg[binary]==3.2.1. If pip install reports no matching distribution, check your Python version first — this is not a stale pin.

psycopg-binary 3.2.1 only ships prebuilt wheels for CPython 3.83.12 (confirmed against https://pypi.org/project/psycopg-binary/3.2.1/#files). Under Python 3.13+ there is no wheel, so pip either falls back to a from-source build (needs libpq dev headers you probably don't have) or fails outright with "No matching distribution."

The project's production image is python:3.12-slim (see backoffice/app/Dockerfile and the tzdata comment in requirements.txt), so the fix is to match that Python version everywhere — local venv, CI, prod — rather than bump the pin. Use python3.12, or the python:3.12-slim container recipe above if your machine doesn't have 3.12 installed.

CI

This suite runs automatically on every push/PR touching backoffice/app/** or backoffice/db/**, via .gitea/workflows/test-backoffice.yml. A local run before pushing is a fast pre-check, not the only gate.