Testing
Testing Pyramid
Section titled “Testing Pyramid”- 70% Unit Tests — fast, isolated, test business logic
- 20% Integration Tests — API endpoints + database
- 10% E2E Tests — critical user flows
Quick Start
Section titled “Quick Start”cd backendpytest # Run all testspytest -v # Verbose outputpytest -m unit # Only unit testspytest --cov=app # With coverageDatabase Testing
Section titled “Database Testing”We use SQLite for local testing (fast, no Docker dependency) with a PortableJSON type adapter. This is a pragmatic trade-off:
| Aspect | SQLite (Current) | PostgreSQL (Better) |
|---|---|---|
| Speed | 2 seconds | 10-30 seconds |
| Setup | None | Docker required |
| Accuracy | 80% | 100% matches production |
Migration path: Testcontainers with real PostgreSQL when the project matures.
FastAPI Testing Pattern
Section titled “FastAPI Testing Pattern”# Use dependency_overrides, NOT unittest.mock.patchapp.dependency_overrides[get_db] = _override_get_dbapp.dependency_overrides[get_current_active_user] = _override_auth
yield TestClient(app)app.dependency_overrides.clear()Model Evals
Section titled “Model Evals”Systematic tests for AI model outputs — accuracy, hallucination rate, cost, latency. Custom eval framework with:
- Pydantic-typed eval datasets
- Domain-specific metrics (calorie error, protein error)
- Multi-model comparison (OpenAI vs Claude vs Gemini)
- CI/CD integration (trigger with
[evals]in commit message)
See the Evals page for the full guide.
Tests run on every push/PR via GitHub Actions:
- Backend pytest (Python 3.9, 3.10, 3.11)
- Frontend typecheck + lint
- Model evals (main branch only)
- Build check
Current coverage threshold: 30% (goal: 80%).