# Frontend Testing Design — Vitest + MSW + Playwright **Ziel:** Vollständige Testabdeckung des Frontends — Hooks, Services, Pages (Unit/Integration) + E2E Browser-Tests. **Stack:** Vitest, @testing-library/react, MSW (Mock Service Worker), Playwright --- ## 1. Test-Infrastruktur ### Dependencies ``` # Unit/Integration vitest @vitest/coverage-v8 jsdom @testing-library/react @testing-library/jest-dom @testing-library/user-event msw # E2E @playwright/test ``` ### Konfiguration - `vitest.config.ts` — erweitert `vite.config.ts`, environment: `jsdom`, setup-Datei - `frontend/src/test/setup.ts` — `@testing-library/jest-dom` Matchers, MSW Server beforeAll/afterEach/afterAll - `frontend/src/test/mocks/handlers.ts` — MSW Request-Handler für alle API-Endpoints - `frontend/src/test/mocks/server.ts` — MSW Server-Instanz - `frontend/src/test/mocks/data.ts` — Mock-Daten (Cases, Users, Dashboard, etc.) - `frontend/src/test/utils.tsx` — `renderWithProviders()` Wrapper (QueryClientProvider + AuthContext + BrowserRouter) - `playwright.config.ts` — E2E Config, baseURL `http://localhost:5173` ### Verzeichnisstruktur ``` frontend/src/test/ ├── setup.ts ├── utils.tsx └── mocks/ ├── server.ts ├── handlers.ts └── data.ts frontend/src/hooks/__tests__/ ├── useDashboard.test.ts ├── useCases.test.ts ├── useDisclosures.test.ts ├── useAuditLog.test.ts ├── useUsers.test.ts ├── useNotifications.test.ts └── useReports.test.ts frontend/src/services/__tests__/ ├── api.test.ts ├── authService.test.ts └── disclosureService.test.ts frontend/src/pages/__tests__/ ├── DashboardPage.test.tsx ├── CasesPage.test.tsx ├── DisclosuresPage.test.tsx ├── AdminAuditPage.test.tsx ├── AdminUsersPage.test.tsx ├── ReportsPage.test.tsx ├── LoginPage.test.tsx ├── ImportPage.test.tsx ├── AccountPage.test.tsx └── ProtectedRoute.test.tsx frontend/e2e/ ├── auth.spec.ts ├── dashboard.spec.ts ├── cases.spec.ts └── admin.spec.ts ``` ### Scripts ```json "test": "vitest run", "test:watch": "vitest", "test:coverage": "vitest run --coverage", "test:e2e": "playwright test" ``` --- ## 2. Unit-Tests — Custom Hooks (~50 Tests) Alle Hooks mit `renderHook()` + MSW testen. Frischer QueryClient pro Test. | Hook | Tests | |------|-------| | `useDashboard(jahr)` | Erfolg, Error, Jahr-Wechsel refetcht | | `useCases(filters)` | Erfolg, leer, Filter-Varianten, `enabled: false` | | `usePendingIcdCases()` | Erfolg, leer, `enabled: false` | | `useCaseUpdate()` | Erfolg, Error, Cache-Invalidierung `['cases']` | | `useKvnrUpdate()` | Erfolg, Error, Cache-Invalidierung `['cases']` | | `useIcdUpdate()` | Erfolg, Error, invalidiert `['cases']` + `['dashboard']` | | `useDisclosures(status)` | Erfolg, leer, Status-Filter | | `useReviewDisclosure()` | Approve, Reject, Error, invalidiert `['disclosures']` + `['notifications']` | | `useAuditLog(filters)` | Erfolg, leer, Filter-Kombinationen | | `useUsers()` | Erfolg, leer | | `useCreateUser()` | Erfolg, Validation-Error, Cache-Invalidierung | | `useUpdateUser()` | Erfolg, Error, Cache-Invalidierung | | `useNotifications()` | Erfolg, Polling, markAsRead, markAllAsRead, refresh | | `useReports()` | Erfolg, leer | | `useGenerateReport()` | Erfolg, Error, Cache-Invalidierung | | `useDeleteReports()` | Erfolg, Error, Cache-Invalidierung | --- ## 3. Unit-Tests — Services (~25 Tests) Services mit MSW testen (echte HTTP-Requests abfangen). | Service | Tests | |---------|-------| | **api.ts** | Token-Attachment, 401 → Auto-Refresh, Refresh-Failure → Redirect, Base-URL | | **authService.ts** | login Erfolg/Error, register, logout (Token-Cleanup), refreshAccessToken, getProfile, updateProfile, MFA-Endpoints (setup, verify, disable), uploadAvatar | | **disclosureService.ts** | requestDisclosure Erfolg/Error, getDisclosureRequests mit Status, reviewDisclosure approve/reject | --- ## 4. Integration-Tests — Pages (~60 Tests) Pages mit `renderWithProviders()` rendern (QueryClient + Router + Auth). MSW liefert Daten. | Page | Tests | |------|-------| | **DashboardPage** | KPIs laden, Jahres-Wechsel, Tortendiagramm (0-Werte gefiltert), Skeleton, Error | | **CasesPage** | Liste rendert, Filter (Suche, Jahr, Fallgruppe, ICD), Pagination, Detail-Sheet, Inline-Edit, ICD-Save, pendingIcdOnly | | **DisclosuresPage** | Liste, Approve/Reject-Buttons, leer, Loading | | **AdminAuditPage** | Einträge laden, Filter, Reset, Pagination, Expandable | | **AdminUsersPage** | Liste, Create-Dialog, Edit-Dialog, Validation, isPending | | **ReportsPage** | Liste, Generieren, Download, Löschen, Checkbox | | **LoginPage** | Erfolg → Redirect, Fehler, Validation | | **ImportPage** | Upload, Preview, Bestätigung, Fehler | | **AccountPage** | Profil, Passwort, MFA, Avatar | | **ProtectedRoute** | Redirect ohne Auth, Admin-Guard, Loading | --- ## 5. E2E-Tests — Playwright (~20 Tests) Gegen echtes Frontend + Backend. Braucht laufendes Dev-Backend auf `localhost:8000` und Test-User. | Spec | Szenarien | |------|-----------| | **auth.spec.ts** | Login gültig → Dashboard, Login ungültig → Error, Logout → Redirect, Protected Route → Redirect | | **dashboard.spec.ts** | KPI-Cards sichtbar, Jahres-Wechsel, Tortendiagramm aktive Fallgruppen | | **cases.spec.ts** | Liste lädt, Suche filtert, Detail-Sheet, Feld bearbeiten + speichern, ICD speichern | | **admin.spec.ts** | User anlegen, User bearbeiten, Audit-Log filtern, Disclosure approve/reject | --- ## Gesamtumfang | Kategorie | Anzahl Tests | |-----------|-------------| | Hook Unit-Tests | ~50 | | Service Unit-Tests | ~25 | | Page Integration-Tests | ~60 | | E2E Browser-Tests | ~20 | | **Gesamt** | **~155** |