Testing Guide

Testing Guide

Owner: Engineering Last reviewed: 2026-Q2

This guide defines how we write and run tests in this repo.

Principles

  • Test behaviour, not implementation. Verify what the code does, not how it does it.
  • Only use the public interface. Do not reach into internals to verify behaviour.
  • Do not test what the type system guarantees. Focus on runtime behaviour, not type correctness.
  • Cover edge cases and error paths. Include invalid input, unauthorized requests, missing resources, and failure scenarios, not just the happy path.
  • Name tests descriptively. Use the pattern test_<scenario>_<expected_outcome>, for example test_upload_file_without_auth_returns_401.
  • Use pytest with httpx.AsyncClient for endpoint tests. Mock all external dependencies such as Azure Blob Storage, Clerk, and OpenAI so tests never hit real services.

Backend

Backend tests live under backend/py/tests.

  • Route tests belong in backend/py/tests/test_routes.
  • Service tests belong in backend/py/tests/test_services.
  • Core/auth tests belong in backend/py/tests/test_core.
  • Shared fixtures and helpers live in backend/py/tests/conftest.py and backend/py/tests/helpers.py.

Run from backend/py:

pytest tests/
pytest tests/test_routes/
pytest tests/test_services/

Use route tests for request/response contracts, dependency wiring, status codes, and auth boundaries. Use service tests for business rules, data access, ranking, sharing, permission decisions, and edge cases.

External Dependencies

  • Mock Clerk JWT/JWKS behavior unless the test is explicitly about token verification.
  • Mock Azure Blob Storage, Azure OpenAI, Azure Vision, Azure Document Intelligence, and network calls.
  • Keep tests deterministic: no real credentials, no real cloud resources, no clock-sensitive assertions without fixed time.

Database And Migrations

  • Add migration tests or model-mapping tests when schema changes affect ORM mappings, cascades, ownership, or permissions.
  • Prefer additive, backward-compatible migrations. Document destructive migrations and rollback expectations in the PR.
  • Run Alembic locally when changing models:
alembic upgrade head

Frontend

  • Always run npm run lint and npm run build from frontend for frontend changes.
  • Prefer component or integration tests for complex UI states, forms, drag/drop behavior, permission-sensitive rendering, and error handling.
  • Regenerate Orval clients after OpenAPI changes and do not hand-edit generated files.
  • See frontend-ux-standards.md for UI state and accessibility expectations.

Run from frontend:

npm run lint
npm run build
npm run orval

Review Expectations

  • Every behavior change should include a test unless the change is documentation-only, generated-only, or explicitly impractical.
  • Risky changes need broader coverage: auth, authorization, migrations, sharing, file upload, billing/entitlements, AI/provider calls, and data deletion.
  • PR descriptions should state what was tested locally and which external dependencies were mocked.