# Tests — Accessible Video Processing Platform ## Test Commands ### Backend | Command | Description | |---------|-------------| | `cd backend && poetry run pytest` | Run all unit tests | | `cd backend && poetry run pytest -v` | Verbose output | | `cd backend && poetry run pytest tests/unit/test_security.py` | Single file | | `cd backend && poetry run pytest -k "test_jwt"` | Keyword filter | | `docker compose exec api python -m pytest` | Tests inside Docker container | | `docker compose exec api python -m pytest --cov=app` | With coverage report | ### Frontend | Command | Description | |---------|-------------| | `cd frontend && npm run test` | Vitest unit tests (watch mode) | | `cd frontend && npm run test:run` | Vitest single run | | `cd frontend && npm run test:coverage` | Coverage report | | `cd frontend && npm run test:e2e` | Playwright E2E tests | | `cd frontend && npx playwright test --ui` | Playwright UI mode | ### Lint and Type Check (must pass before commit) | Command | Description | |---------|-------------| | `cd backend && ruff check .` | Python linting | | `cd backend && poetry run mypy app/` | Python type checking | | `cd frontend && npm run lint` | ESLint | | `cd frontend && npm run type-check` | TypeScript compile check | --- ## Test Structure ### Backend (`backend/tests/`) | Directory | Purpose | Framework | |-----------|---------|-----------| | `tests/unit/` | Business logic unit tests | pytest | | `tests/fixtures/` | VTT and JSON test fixtures | — | | `tests/integration/` | FastAPI TestClient route tests | pytest (does not exist yet) | | `conftest.py` | Shared fixtures | pytest (does not exist yet) | ### Frontend (`frontend/src/` and `frontend/tests/`) | Directory | Purpose | Framework | |-----------|---------|-----------| | `src/**/__tests__/` | Component unit tests | Vitest + RTL | | `src/hooks/__tests__/` | Hook tests | Vitest + RTL | | `src/lib/__tests__/` | Utility tests | Vitest | | `src/test/utils.tsx` | Shared test utilities | RTL | | `tests/e2e/` | End-to-end specs | Playwright | | `tests/helpers/auth.ts` | Auth fixture (exists, not yet wired) | Playwright | --- ## Coverage Targets | Layer | Target | Current | |-------|--------|---------| | Backend unit | 80% line coverage on services/ | ~3% (critically low) | | Frontend unit | 70% branch coverage on hooks/ | ~12% | | E2E | All happy paths for QC workflow | 0% (tests skipped) | --- ## Writing New Tests ### Backend Unit Test Pattern ```python # Use AsyncMock for async service methods from unittest.mock import AsyncMock, patch async def test_something(): with patch('app.services.gemini.settings') as mock_settings: mock_settings.gemini_api_key = "test-key" # test body ``` Wait — **move the settings mock to a shared fixture in conftest.py**. See anti-patterns in [testing-strategy.md](../docs/reference/guides/testing-strategy.md). ### Frontend Hook Test Pattern Use `renderHook` from `@testing-library/react` wrapped with `test/utils.tsx` providers. ### E2E Auth Pattern Use `tests/helpers/auth.ts` in `beforeEach`: ```typescript // Wire auth fixture before un-skipping any test test.beforeEach(async ({ page }) => { await loginAs(page, 'reviewer'); }); ``` --- ## Known Issues | Issue | Impact | Fix needed | |-------|--------|-----------| | `conftest.py` missing | All tests define fixtures inline | Create shared conftest with MockSettings, mock_db | | E2E tests mostly skipped | Zero E2E coverage | Implement auth + seed fixtures | | `MagicMock` used for async services | May silently pass on sync mocks | Replace with `AsyncMock` | | Hardcoded `test-job-123` in E2E | Tests would fail if un-skipped | Use seed fixtures | --- ## Maintenance **Update triggers:** New test file added, test framework version changed, new command available. **Verification:** All commands in the Commands section execute without error on a clean checkout.