Skip to main content

Backend tests

Tests live in backend/tests/ and are named test_<feature>_<layer>.py. Run them from the backend/ directory with the virtual environment activated.

Running tests

Run the full suite against SQLite (fast, no external dependencies):
Run a single test file:
Run a single test by name:

Dual-backend suite

The test suite runs every database test against both SQLite and Postgres. SQLite runs by default; Postgres requires Docker (via testcontainers) and is enabled with:
CI always runs both legs. Locally, SQLite-only is sufficient for day-to-day development. Before submitting a migration or a change that touches queries, run the full dual-backend suite to catch portability regressions.

DB fixtures and sync context

The conftest.py fixtures that run Alembic migrations are synchronous (pytest.fixture, not pytest_asyncio.fixture). This is intentional: Alembic’s env.py uses asyncio.run() internally, so migrations must be driven from a sync context. Async session fixtures are layered on top after migrations complete. The fake_salt_api fixture provides an httpx.MockTransport-backed fake salt-api. Tests configure its responses via attribute assignment and pass transport=fake_salt_api.transport when constructing a SaltAPIClient.

Lint and format

Halite uses ruff for linting and formatting. Run from backend/:
Configuration: line length 100 (E501 ignored), rules E, F, W, I, B, UP, SIM.

Frontend tests

Run from the frontend/ directory:
Run npm run build before pushing frontend changes. The build step runs tsc -b which catches type errors that vitest may not surface.