# Testing & Code Quality — Social Proximity ## Scope These rules apply to the **Python backend** (`backend/`). The Flutter app and Next.js admin have separate tooling. Quality analysis runs via **DevOpsMCP** — a set of code analysis tools accessible through the MCP server at `https://devops-mcp.i80.dk`. --- ## When to Run What | Tool | Trigger | Threshold | |---|---|---| | `check_pep_compliance` | Before every commit | Zero violations | | `check_personal_standards` | Before every commit | Zero `error`-level findings | | `analyze_complexity` | When writing functions > 20 lines | Max cyclomatic complexity: **8** | | `add_type_hints` | When adding new functions | Min type hint coverage: **80%** | | `analyze_missing_docstrings` | New classes and public functions | No missing docstrings on public API | | `analyze_yaml` + `analyze_github_actions` | When editing Gitea CI/CD workflow files | Zero security violations | --- ## Coding Standards (Python backend) ### Enforced by `check_personal_standards` - **No `subprocess` with `shell=True`** — use SDK clients instead - **No bare `except:`** — always catch specific exceptions - **No `%` or `.format()` string formatting** — use f-strings - **No mutable default arguments** — use `None` and set inside function body - **No hardcoded secrets** — use environment variables via `pydantic-settings` ### Enforced by `analyze_complexity` - Max cyclomatic complexity per function: **8** - Functions exceeding this must be refactored (extract helper functions) ### Enforced by `add_type_hints` - All function parameters must have type annotations - All function return types must be annotated - Use `Optional[T]` or `T | None` — not bare `None` returns without annotation --- ## Workflow ``` 1. Write code 2. Run check_personal_standards(file) → fix all 'error' findings 3. Run analyze_complexity(file) → refactor if any function > 8 4. Run add_type_hints(file, apply_changes=False) → review suggestions, apply manually 5. Run check_pep_compliance(file) → fix formatting 6. Commit ``` --- ## Test Strategy (backend) Tests live in `backend/tests/` and use **pytest**. | Layer | What to test | Example | |---|---|---| | Unit | Service logic in isolation | `test_match_service.py` — interest overlap calculation | | Integration | API endpoints with real Redis/DB | `test_session.py` — POST /session creates Redis key | | Contract | Request/response shapes match Pydantic models | Via pytest + httpx TestClient | **Run tests:** ```bash cd backend pytest tests/ -v ``` --- ## Flutter App Testing | Layer | Tool | Notes | |---|---|---| | Unit | `flutter test` | Test service logic, models | | Widget | `flutter test` + `WidgetTester` | Test UI components in isolation | | Integration | `flutter drive` | Requires physical device or emulator | BLE scanning cannot be tested in emulators — use a physical device for BLE integration tests. --- ## DevOpsMCP Quick Reference ```python # Upload file and run analysis session = DevOpsMCP-start_project_session("sighej-backend", [ {"file_path": "main.py", "content": ""} ]) DevOpsMCP-check_personal_standards(file_path="main.py") DevOpsMCP-analyze_complexity(file_path="main.py") DevOpsMCP-add_type_hints(file_path="main.py", apply_changes=False) DevOpsMCP-check_pep_compliance(file_path="main.py") DevOpsMCP-generate_tests(file_path="main.py") ```