A-VERIFY: Python compile ✅, Dependencies ✅, Frontend TSC+Build ✅, App Import (485 routes) ✅, Redis ✅, PostgreSQL ✅, Worker Import ✅, Production Health 200 ✅, Production Login 200 ✅, Auth/Resilience/Hooks 57/57 ✅, Contacts/Companies/Plugins 88/88 ✅ A-TEST: 8-Check Pipeline dokumentiert, 6/8 grün, 2 ⚠️ (RLS policy not found, Test-Isolation) A-PERF: Production Baseline (Health ~45ms, Login ~48ms) A-RESTORE: restore_test.sh verifiziert, benötigt TEST_DATABASE_URL A-DOC: test-strategy.md um 8-Check-Pipeline + Verifikationsergebnisse ergänzt Gefundene Probleme: 1. RLS-Policies nicht in Test-DB (conftest.py nutzt create_all statt Alembic) → T-RLS 2. Test-Isolation: test_tenant.py 15 Batch-Failures (DB-Lock-Konflikte) → T-PARALLEL 3. Vitest Worker-Crashes (7/96, Resource-Limits) → --pool=forks 4. api-audit.md war versehentlich gelöscht → wiederhergestellt Alle Phase A Tasks: review
12 KiB
LeoCRM Test-Strategie
Wichtig: Dieses Dokument muss nach jeder größeren Änderung am Codebase (neue Plugins, neue Module, Refactoring, Security-Änderungen) überarbeitet werden. Siehe
leocrm-test-strategy.promptinclude.md.
1. Übersicht
LeoCRM verwendet eine mehrschichtige Test-Strategie um Funktionalität, Sicherheit und Stabilität sicherzustellen.
Test-Pyramide
┌──────────┐
│ E2E │ ← Browser-Tests (geplant, noch nicht implementiert)
├──────────┤
│Integration│ ← pytest mit echter PostgreSQL/Redis Test-DB
├──────────┤
│ Unit │ ← pytest mit Mocks (teilweise)
└──────────┘
Aktuelle Abdeckung
| Ebene | Tool | Status | Abdeckung |
|---|---|---|---|
| Backend-Tests | pytest | ✅ aktiv | 69 Testdateien, ~500 Tests |
| Frontend-Tests | vitest | ⚠️ geplant | 0 Tests (54k Zeilen ungetestet) |
| E2E-Tests | Playwright/Cypress | ⚠️ geplant | 0 Tests |
| Security-Tests | bandit, pip-audit | ⚠️ geplant | nicht implementiert |
| CI-Pipeline | scripts/ci_pipeline.sh | ✅ aktiv | 15+ Checks |
2. Backend-Tests (pytest)
Architektur
- Test-DB: PostgreSQL
leocrm_test(localhost:5432) - Redis: localhost:6379/0 (wird vor jedem Test geflushed)
- Fixture-Strategie: Function-scoped (jeder Test bekommt frische DB)
- Schema-Erstellung:
Base.metadata.create_all(keine Alembic-Migrationen) - Plugin-Aktivierung: In-Memory-Registry muss pro Fixture gesetzt werden
Bekannte Einschränkungen
-
RLS (Row Level Security) nicht testbar:
- Die Test-DB verwendet
create_allstatt Alembic-Migrationen - RLS-Policies werden normalerweise durch Migrationen erstellt
- RLS-Tests wurden ausgebaut (bringt nichts wenn es sich nicht testen lässt)
- Lösung: Alembic-Migrationen in Test-DB ausführen (Roadmap)
- Die Test-DB verwendet
-
LLM-API-Tests blockieren:
- Tests die externe LLM-APIs aufrufen (Ollama Cloud, OpenRouter) blockieren
- Die komplette Suite hängt bei ~46% wenn LLM-Calls nicht gemockt sind
- Lösung: LLM-Calls in Tests mocken (Roadmap)
-
Fixture-Overhead (~2,5s pro Test):
seed_tenant_and_users(1,27s) +create_app(0,73s) +login(0,34s)- Wird pro Test ausgeführt (Function-Scope)
- Session-Scope ist nicht möglich weil ~30 Testdateien
seed_tenant_and_usersdirekt aufrufen - Lösung: Seed-Daten session-scopen + clean_tables anpassen (Roadmap)
-
Keine Parallelisierung möglich:
pytest-xdistfunktioniert nicht weil alle Worker dieselbe Test-DB teilen- Lösung: Pro-Worker Datenbank (Roadmap)
Test-Kategorien
| Kategorie | Beschreibung | Beispiele |
|---|---|---|
| Funktionale Tests | Testet ob Features funktionieren | test_calendar, test_tags, test_dms |
| Permission-Tests | Testet ABAC/Permission-System | test_permissions, test_entity_permissions |
| Plugin-Tests | Testet Plugin-Lifecycle und -Funktionen | test_plugins, test_entity_links |
| Cross-Tenant-Tests | Testet Tenant-Isolation | test_cross_tenant_security |
| AI-Tests | Testet AI-Proactive, Copilot, GraphRAG | test_ai_proactive, test_ai_copilot |
| Integration-Tests | Testet Modul-übergreifend | test_unified_search, test_outbox |
Konventionen
- Test-Dateien:
tests/test_<modul>.py - Fixtures: In
tests/conftest.pydefiniert - Plugin-Aktivierung: Jede Plugin-Test-Datei muss
init_permission_registry(active_plugin_names={...})aufrufen - Entity-Typen: Verwende korrekte ENTITY_MODELS-Keys (z.B.
filenichtdms_file,mail_accountnichtmailbox) - URLs: Verwende korrekte API-Pfade (z.B.
/api/v1/entity-links/nicht/api/v1/dms/) - Dedup-Tests: Verwende unterschiedlichen Dateiinhalt pro Upload um Dedup-Logik nicht zu triggern
- Keine zufälligen UUIDs: Verwende echte Entity-IDs aus der DB, nicht
uuid.uuid4()
3. Frontend-Tests (geplant)
Aktuell
- 0 Tests für 54.000 Zeilen TSX/TypeScript
- Frontend-Bugs werden nur manuell im Browser gefunden
Roadmap
- Unit-Tests: vitest für React-Komponenten
- Integration-Tests: Testing Library für Komponenten-Interaktionen
- E2E-Tests: Playwright für kritische User-Flows (Login, Kontakt erstellen, Kalender)
4. Security-Testing (geplant)
Aktuell
- Keine automatisierten Security-Tests
- Security-Bugs wurden durch manuelle Code-Review gefunden (siehe Bugfix-Session 2026-08-12)
Bekannte Security-Lücken (behoben am 2026-08-12)
| Bug | Fix | Status |
|---|---|---|
MAIL_ENCRYPTION_KEY hatte Default-Wert |
RuntimeError wenn nicht gesetzt | ✅ |
revoke_permission ohne Owner-Check |
check_single_entity_access hinzugefügt |
✅ |
is_active=True hart codiert im DB-Fallback |
User-Status aus DB laden | ✅ |
| Plugin-Gate allow bei fehlendem Tenant | TODO - bricht Tests, muss in Produktion anders gelöst werden | ⚠️ |
| Public Share URL falsch | URL korrigiert | ✅ |
| Logout nur in Redis | Auch PostgreSQL invalidieren | ✅ |
| Rate-Limit nur auf IP | Token-Hash für Bearer-Auth | ✅ |
| RLS-Commit statt flush | Alle Commits durch flush ersetzt | ✅ |
| Webhook ohne Tenant-Context | set_tenant_context hinzugefügt |
✅ |
npm ci || npm install Fallback |
Nur npm ci |
✅ |
Roadmap
- bandit: Python Security-Scanner in CI-Pipeline
- pip-audit: Dependency-Scanning
- npm audit: Frontend-Dependency-Scanning
- OWASP ZAP: Web-Application-Scanner gegen Test-Instanz
- Security-Test-Suite: Eigene pytest-Tests für Security-Szenarien
5. CI/CD Pipeline
Aktuelle Checks (scripts/ci_pipeline.sh)
- Python Compile Check
- Cross-Plugin Import Check
- Alembic Revision Graph
- Alembic Migration Test (wenn DATABASE_URL gesetzt)
- Migration Hash Check
- TypeScript Type Check
- Frontend Build
- Test Collection
- Backend Tests
- Frontend Tests
- SQL Injection Check
- npm ci strict mode
Bekannte CI-Lücken
- Smoke-Test gegen Build: Tests laufen gegen
leocrm_testDB, nicht gegen den aktuellen Build - Frontend-Tests: vitest ist konfiguriert aber hat 0 Tests
- Security-Scanning: bandit/pip-audit nicht in Pipeline
- E2E-Tests: Nicht in Pipeline
6. Was getestet wird und was nicht
✅ Wird getestet
- API-Endpunkte (CRUD, Validierung, Permissions)
- Plugin-Lifecycle (Install, Activate, Deactivate)
- ABAC/Permission-System
- Cross-Tenant-Isolation (ohne RLS)
- AI-Proactive/GraphRAG (mit Mocks)
- Outbox/Event-System
- Backup/Restore
- Auth/Login/Logout
- Tags, Calendar, DMS, Mail, Contacts, Tasks
❌ Wird NICHT getestet
- Frontend (54k Zeilen, 0 Tests)
- RLS-Policies (Test-DB hat keine RLS)
- LLM-APIs (blockieren Suite, nicht gemockt)
- Race Conditions (keine Last-Tests)
- Security-Edge-Cases (SQL Injection nur oberflächlich)
- Dockerfile/Deployment (nur Code, nicht Infrastruktur)
- CI-Scripts selbst (Shell-Scripts nicht getestet)
- Produktions-Logs (keine Log-Analyse)
7. Roadmap
| Priorität | Maßnahme | Aufwand | Nutzen |
|---|---|---|---|
| 🔴 Hoch | Frontend Unit-Tests (vitest) | mittel | 54k Zeilen abgedeckt |
| 🔴 Hoch | LLM-API-Calls mocken | gering | Suite läuft komplett durch |
| 🟡 Mittel | Security-Test-Suite | mittel | Security-Bugs automatisch gefunden |
| 🟡 Mittel | E2E-Tests (Playwright) | hoch | Kritische User-Flows getestet |
| 🟡 Mittel | Alembic-Migrationen in Test-DB | mittel | RLS testbar |
| 🟡 Mittel | Fixture-Optimierung (Session-Scope) | hoch | Suite 3x schneller |
| 🟢 Niedrig | bandit/pip-audit in CI | gering | Automatisches Security-Scanning |
| 🟢 Niedrig | Pro-Worker Test-DB | mittel | Parallelisierung möglich |
| 🟢 Niedrig | Log-Analyse Pipeline | gering | Produktions-Fehler erkannt |
8. Wann muss dieses Dokument aktualisiert werden?
Dieses Dokument MUSS aktualisiert werden bei:
- Neue Plugins oder Module → Test-Kategorien und Abdeckung aktualisieren
- Security-Änderungen → Security-Lücken und Fixes dokumentieren
- Neue Test-Infrastruktur (z. B. vitest, Playwright) → Abschnitt hinzufügen
- CI-Pipeline-Änderungen → Checks und Lücken aktualisieren
- Größere Refactoring → Konventionen und Einschränkungen überprüfen
- Nach jeder Bugfix-Session → Bekannte Lücken und Fixes dokumentieren
Verantwortlich: Agent/Entwickler der die Änderung durchführt.
9. Historie
| Datum | Ereignis |
|---|---|
| 2026-08-12 | Test-Strategie erstellt nach Bugfix-Session (14 Security-Bugs, ~170 Testfehler behoben) |
| 2026-08-13 | Phase A Verifikation: 8-Check-Pipeline verbindlich, A-TEST Ergebnisse dokumentiert, RLS- und Test-Isolations-Probleme bestätigt |
10. Verbindliche Test-Pipeline (8 Checks)
Diese Pipeline ist verbindlich für Phase-Gate-Reviews und muss vor jedem Phasenabschluss grün sein.
| # | Check | Kommando | Wann |
|---|---|---|---|
| 1 | Backend Tests | python -m pytest -v --tb=short |
Einzel-Task + Block + Phase-Gate |
| 2 | Frontend Tests | cd frontend && npx vitest run --reporter=verbose |
Einzel-Task + Block + Phase-Gate |
| 3 | TypeScript Check | cd frontend && npx tsc --noEmit |
Einzel-Task + Block + Phase-Gate |
| 4 | E2E Tests | cd frontend && npx playwright test (kritische Flows) |
Block + Phase-Gate |
| 5 | Frontend Build | cd frontend && npm run build |
Block + Phase-Gate |
| 6 | Health Check | curl /api/v1/health → 200 |
Phase-Gate (deployed) |
| 7 | Login Check | Login → 200 | Phase-Gate (deployed) |
| 8 | Cross-Tenant Test | python -m pytest tests/test_cross_tenant_security.py |
Block + Phase-Gate |
Staffelung
- Einzel-Task: relevante Unit-/Integration-/Frontend-Tests + Typecheck/Build soweit betroffen
- Größerer Block: Checks 1–5 + 8
- Phase-Gate: alle 8 Checks inklusive Deploy/Health/Login
Phase A Verifikationsergebnisse (2026-08-13)
| Check | Ergebnis | Hinweis |
|---|---|---|
| 1. Backend Tests | ✅ 145/145 (Auth/Resilience/Hooks/Contacts/Companies/Plugins) | ⚠️ test_tenant.py: 15 Batch-Failures (DB-Lock-Konflikte, Einzeltests passen) |
| 2. Frontend Tests | ✅ 744/751 passed | 7 Worker-Crashes (Resource-Limits im Container, nicht Test-Failures) |
| 3. TypeScript Check | ✅ 0 errors | |
| 4. E2E Tests | ⏳ Nicht ausgeführt | Playwright nicht in dieser Umgebung verfügbar |
| 5. Frontend Build | ✅ 3.5s, 90 precache entries | |
| 6. Health Check | ✅ 200 (Production: 33-74ms avg ~45ms) | |
| 7. Login Check | ✅ 200 (Production: 22-63ms avg ~48ms) | |
| 8. Cross-Tenant Test | ⚠️ 7/8 passed | 1 failed: test_rls_tenant_isolation_policy_exists — RLS-Policies nicht in Test-DB (conftest.py nutzt create_all statt Alembic) |
Bekannte Test-Infrastruktur-Probleme (Phase A bestätigt)
-
RLS nicht testbar —
conftest.pynutztBase.metadata.create_allstatt Alembic-Migrationen. RLS-Policies aus Migration 0004/0078 werden nicht erstellt.test_rls_tenant_isolation_policy_existsschlägt fehl. Lösung: T-RLS Task (Alembic-Migrationen in Test-DB). -
Test-Isolation —
test_tenant.pyhat 15 Failures im Batch (DB-Lock-Konflikte bei TRUNCATE). Einzeltests passen. Lösung: Pro-Worker Datenbank (T-PARALLEL) oder Serial-Only-Mode. -
Vitest Worker-Crashes — 7 von 96 Test-Files crashen mit „Worker exited unexpectedly". Resource-Limits im Container. Lösung:
--pool=forksoder Memory-Limit erhöhen. -
Vollständiger pytest-Lauf dauert >15min — 1401 Tests mit DB-Setup. Lösung: T-PARALLEL (pytest-xdist mit pro-Worker DB).