Skip to content

Backend testing guidelines (internal)

This doc describes the backend testing expectations and how to run checks locally.

If you want step-by-step “run the app and click it” workflows, use:

  • live-testing.md

From the repo root:

  • make backend-ci (fast backend CI gate: format check, lint, typecheck, tests)
  • make prepush (GitHub-parity pre-push gate: make check + local API-health verification + CI-aligned pip-audit policy)
  • make check-full (optional: pre-commit, security scan, docs build/lint)

make backend-ci is intentionally kept low-friction so it can run constantly without blocking development. Use make check-full before deploys or when you want stricter validation.

Notes:

  • make backend-ci runs the same fast backend gate as make ci, including make test-fast.
  • make test-all runs the full test suite.
  • Browser automation suites (for example Playwright in related repos) should run in CI by default; only run them locally when you explicitly need interactive debugging.

End-to-end smoke (public surface)

CI also runs a fast end-to-end smoke check that starts the backend + frontend locally from one checkout and verifies user-critical routes (no browser automation):

  • make integration-e2e
  • equivalent script form: ./scripts/ci-e2e-smoke.sh --frontend-dir frontend
  • If the frontend is already built (CI artifact), add: --skip-frontend-build

In CI, the smoke check runs in .github/workflows/backend-ci.yml on pushes, pull requests, and manual runs from the same checkout.

Running subsets

  • Unit tests: pytest
  • One test file: pytest tests/test_something.py
  • One test: pytest -k some_keyword
  • Lint + format: ruff check . and ruff format --check .
  • Type-check: mypy src tests

Writing tests

  • Put tests in tests/ and prefer plain pytest tests (no custom harness).
  • Keep tests deterministic:
  • avoid real network calls
  • avoid wall-clock dependencies
  • avoid global state between tests
  • If you add a new API route, add at least one test that exercises the route and asserts the key behavior.
  • If you change DB behavior, prefer tests that set up a temporary DB using the existing test fixtures/patterns.

Scope (what belongs in tests vs scripts)

  • Application behavior belongs in tests/.
  • VPS automation scripts under scripts/ should stay simple and safe; when logic grows (parsing, policy evaluation), prefer moving that logic into a small Python module that can be tested.