104 lines
3.3 KiB
Markdown
104 lines
3.3 KiB
Markdown
# 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": "<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")
|
|
```
|