--- trigger: always_on --- ## General Principles - Write unit tests for new features prior to implementing the feature. - Write unit tests for utilities and components. - Maintain 100% test coverage (backend). Frontend coverage threshold follows CI config (≥90% or 100% for symmetry). - Unit tests should never make external calls. Integration tests may call externals. - Minimize fixtures for generating inputs; prefer explicit inline inputs/expectations. - Tests should be written as functions (avoid class-based tests). - Use descriptive, intention-revealing names (e.g., `isCreated`, `hasError`) and prefer iteration/modularization over duplication. ## Test Structure ### Top-level Layout - `tests/unit/` for pure unit tests (no external I/O). - `tests/integration/` for tests allowed to hit external services. ### Granular Python Unit Test Organization 1. Use a directory per module under test (e.g., `tests/unit/app/services/estimating/`). 2. Within that directory, use a file per function under test (e.g., `test_calculate_estimate.py`). 3. Keep unit and integration tests in separate trees: `tests/unit/` and `tests/integration/`. ### Naming and Scope - Only test functionality in the module under test; don’t re-test validation or logic implemented elsewhere. - Do not introduce coverage-only test files (e.g., files named with “additional_coverage”, “remaining_branches”, “misc_coverage”). - When adding a new test file, name it by feature or unit under test (e.g., `test_service_delete_update.py`). ## Backend (FastAPI) Testing ### Framework - Pytest ### Coverage and Practices - Prefer tests over no-cover. - Avoid `# pragma: no cover` except in strictly justified cases: - Optional dependency branches or platform guards - Defensive/unreachable paths in supported environments - Use `pytest-mock`’s `mocker` fixture for mocking. - Use monkeypatches to control `time.sleep`, `random.random`, etc., to keep tests fast/deterministic. - For network-like behavior, write light fakes with only the attributes used by the code under test. - If a safety guard exists (e.g., a best-effort `close()`), add a micro-test to exercise it. ### Commands - Full suite (CI-like): `bash scripts/ci/backend-test.sh` - Ad-hoc (from `backend/`): - All tests (with dev extras): `uv run --with .[dev] -m pytest` - With coverage: `uv run --with .[dev] -m pytest --cov=app --cov-report=term-missing` - Single test/file: `uv run --with .[dev] -m pytest app/tests/unit/path/to/test_file.py::test_case` ### Notes - Dev extras defined under `[project.optional-dependencies].dev` in `backend/pyproject.toml` and include `pytest`, `pytest-cov`. - Pytest config lives under `[tool.pytest.ini_options]` in `backend/pyproject.toml` (e.g., `testpaths = ["app/tests"]`). - Quick run without extras (no coverage): `uv run -m pytest` (no `pytest-cov`). ## Frontend (React or React Native) Testing ### Framework - Jest + Testing Library (React) or Jest + React Native Testing Library (React Native) ### Mocking Guidance - Avoid mocking React/React Native primitives unless necessary. - Mock network via MSW. ### Commands - Full suite (CI-like): `bash scripts/ci/frontend-test.sh` - Ad-hoc (from `frontend/`): - npm: `npm run lint` then `npm test -- --coverage` - pnpm: `pnpm run lint` then `pnpm test -- --coverage` ## End-to-End (E2E) Testing - Implement E2E tests for critical flows. - Choose an appropriate framework based on the frontend: - Web (React): Playwright or Cypress - React Native: Detox - Keep E2E focused on user-critical paths; avoid duplicating unit/integration coverage. ## CI Expectations and Consistency - CI runs from `.gitea/workflows/`. - Required checks: - Backend: ruff, mypy, tests with coverage ≥100%. - Frontend: eslint, jest with coverage thresholds (≥90% or 100% for symmetry). - No merges to main without green pipelines. - Use `scripts/ci/*` to mirror CI logic locally. ## Development Phase Testing (Pre-deployment) - Update tests in the same PR when API contracts change (request/response shapes, validation, or status codes). - Refresh example payloads in schemas and test fixtures together to prevent drift. - Prefer targeted API integration tests for critical endpoints to validate schema and docs alignment.