FleetFlow — Testdokumentation
Testkonzept, Testebenen und manueller Testplan
| |
|---|
| Projekt | FleetFlow — Flottenmanagement für Autovermietungen |
| Stand | 30.07.2026 (main, inkl. Versicherungsmodul) |
| Ergänzend | TESTING.md (historischer Testplan der Feature-Branch-Phase), FEATURE_LOG.md (Verifikationsnachweise je Feature) |
1. Testkonzept
1.1 Prüfebenen
Für jedes Feature wurden während der Entwicklung mehrere Prüfebenen kombiniert. Ein Feature galt erst als abgeschlossen (Definition of Done), wenn alle Ebenen bestanden waren:
| Ebene | Werkzeug / Vorgehen | Prüft |
|---|
| Statische Prüfung | npx tsc --noEmit (TypeScript strict), npm run lint (ESLint) | Typfehler, Stilverstöße, tote Importe |
| Build-Prüfung | npm run build | Fehlerfreier Produktionsbuild, korrekte Routen-Tabelle |
| Datenverifikation | Direkte SQL-Abfragen gegen die (Remote-)Datenbank nach jeder Migration | Erwartete Struktur, Constraints, Seed-Daten, Idempotenz der Migrationen |
| Isolierte Funktionstests | Direkter Aufruf zentraler Funktionen mit konkreten Beispieldaten | Preisberechnung, Verfügbarkeitsprüfung, Auslastungs-/Umsatzaggregation, Warn-Schwellwerte, PDF-Rendering, KI-Fallbacks |
| Sicherheits-/Negativtests | End-to-End-Tests mit Wegwerf-Testkonten, direkte API-Aufrufe ohne Berechtigung | RLS-Policies, 403-Verhalten, Anti-Privilege-Escalation |
| Manuelle UI-Tests | Testplan in Abschnitt 2, Klickpfade je Rolle | Tatsächliches Verhalten in der Anwendung |
1.2 Exemplarische Nachweise aus der Entwicklung
Die Kombination der Ebenen hat mehrfach reale Fehler vor der Auslieferung gefunden — dokumentiert im FEATURE_LOG.md:
- RLS-Datenleck im Kundenportal (#14): Ein End-to-End-Test mit einem Wegwerf-Kundenkonto zeigte, dass das Konto fremde Kunden- und Fahrzeugdaten lesen konnte. Ergebnis: Feature vollständig zurückgebaut, Produktentscheidung „keine Kundenkonten" festgeschrieben.
- Falsch skalierter Warn-Schwellwert (#29): Der Standard-Vorwarnzeitraum (30 Tage) hätte bei einem 30-Tage-Aufbereitungsintervall dauerhaft „bald fällig" angezeigt. Per isoliertem Funktionstest mit konkreten Tagesabständen (0/15/25/40 Tage) gefunden und durch intervall-relative Skalierung behoben.
- Rechteausweitung per Anon-Key (#36): Eine Update-Policy ohne
WITH CHECK erlaubte das Ändern der eigenen Rolle direkt über die Datenbank-API. Durch gezielten Negativtest nachgewiesen, per Migration + Trigger geschlossen, anschließend erneut negativ getestet.
- 2FA-Fallstricke (#44): Zwei reale Bugs (Session-Cache nach
unenroll(), Filterverhalten von listFactors()) wurden beim Testen der Flows gefunden und behoben — dokumentiert in 2fa-technisches-konzept.md, Abschnitt 6.
1.3 Testdaten
- Seed-Migration mit 8 Musterkunden (4 Privat-, 4 Firmenkunden mit realistischen deutschen Firmennamen, USt-IdNrn., Ansprechpartnern).
- Fahrzeuge und Buchungen in allen Workflow-Status als Grundlage der manuellen Durchläufe.
- Für Sicherheits-/Rollentests: eigens angelegte Testkonten je Rolle (inkl. Werkstatt-Testkonto und temporärer Rollen), nach Testende wieder entfernt.
2. Manueller Testplan
Vorbedingungen für alle Testfälle: laufende Anwendung, ein Admin-Konto, ein Mitarbeiter-Konto, ein Werkstatt-Testkonto; mindestens ein Fahrzeug, je ein Privat- und Firmenkunde, Buchungen in verschiedenen Status.
2.1 Authentifizierung & 2FA
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| A1 | Login mit korrektem Passwort, Konto ohne eingerichteten Faktor | Automatische Weiterleitung zur 2FA-Einrichtung (QR-Code); ohne Abschluss kein Zugriff auf interne Seiten |
| A2 | QR-Code mit Authenticator-App scannen, gültigen Code eingeben | Einrichtung erfolgreich, Weiterleitung in die App |
| A3 | Erneuter Login (Faktor vorhanden) | Nach Passwort folgt Code-Abfrage; falscher Code → Fehlermeldung, korrekter Code → Zugriff |
| A4 | Direkter Aufruf einer internen URL (z. B. /vehicles) ohne bestandenen zweiten Faktor | Umleitung zur Code-Abfrage bzw. Einrichtung — kein Vorbeikommen per Lesezeichen |
| A5 | Aufruf von /mfa/enroll mit bereits voll authentifizierter Session | Umleitung in die App (kein erneutes Enrollment) |
| A6 | Faktor unter Einstellungen → Sicherheit zurücksetzen | Beim nächsten Seitenaufruf erzwungene Neueinrichtung per QR-Code |
| A7 | Registrierung aufrufen, obwohl bereits eine Firma eingerichtet ist | Ablehnung mit Hinweis, dass das System bereits eingerichtet ist (HTTP 409) |
2.2 Rollen- und Berechtigungssystem
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| R1 | Login mit Rolle ohne Schreibrecht auf einen Bereich | Bearbeiten-/Neu-Buttons erscheinen nicht; direkter Aufruf der Bearbeiten-URL leitet zur Detailseite zurück |
| R2 | Direkter API-Aufruf ohne Recht (Browser-Konsole, z. B. DELETE /api/vehicles/[id]) | Klare Fehlermeldung mit HTTP 403 — keine stille leere Antwort, keine Ausführung |
| R3 | Neue Rolle anlegen, Berechtigungsmatrix einstellen, Testkonto zuweisen, damit einloggen | Exakt die eingestellten Rechte greifen (Navigation, Buttons, API) |
| R4 | Versuch, Grundrollen (admin/mitarbeiter/kunde) umzubenennen oder zu löschen | Wird verweigert |
| R5 | Rolle eines bestehenden Kontos in der Mitarbeiterliste ändern | Wirkt beim nächsten Seitenaufruf des Betroffenen |
| R6 | Versuch, die eigene Rolle ohne Benutzerverwaltungs-Recht zu ändern (direkt per Datenbank-API/Anon-Key) | Wird durch Datenbank-Trigger abgelehnt |
| R7 | Bereich ohne Leserecht: Menüpunkt sichtbar? | Nein — aus der Seitenleiste ausgeblendet |
2.3 Fahrzeuge
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| F1 | Fahrzeug anlegen mit allen Stammdaten | Erfolgs-Toast, Fahrzeug erscheint in Liste und auf der Karte (bei GPS-Koordinaten) |
| F2 | Filtern nach Status/Typ, Freitextsuche (Kennzeichen/Marke/Modell/VIN), Kombination | Ergebnisse korrekt (UND-Verknüpfung), URL-Parameter gesetzt, Suche debounced |
| F3 | > 50 Fahrzeuge vorhanden | Pagination erscheint („Zeige 1–50 von N"); Filterwechsel springt auf Seite 1 |
| F4 | HU/Service-Termin in < 30 Tagen bzw. überschritten | Warnung auf Liste, Detailseite und Dashboard; Buchung bleibt möglich |
| F5 | Aufbereitung: Intervall in Einstellungen ändern, letzte_aufbereitung zurückdatieren | Warnstufen ok/bald fällig/überfällig entsprechend Intervall; „Aufbereitung abgeschlossen" setzt zurück |
| F6 | Fahrzeug löschen als Rolle ohne Löschrecht | Button deaktiviert mit Tooltip; direkter API-Aufruf → 403 |
2.4 Kunden
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| K1 | Kundentyp im Formular zwischen Privat und Firma umschalten | Felder wechseln korrekt (Vor-/Nachname ↔ Firmenname/Ansprechpartner/USt-IdNr.) |
| K2 | Firmenkunde speichern und Detailseite öffnen | Firma, Ansprechpartner, USt-IdNr. werden angezeigt |
| K3 | Suche nach Name/Firma/E-Mail/Telefon/Ort | Treffer korrekt, serverseitig über den gesamten Bestand |
| K4 | Abgelaufener Führerschein beim Privatkunden | Warnung auf der Kundendetailseite |
| K5 | Kundendetailseite | Vollständige Buchungshistorie sichtbar |
2.5 Buchungen
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| B1 | Buchung anlegen (Fahrzeug, Kunde, Zeitraum) | Preisvorschau mit Faktor-Aufschlüsselung; Speichern mit Toast |
| B2 | Fahrzeug im selben Zeitraum erneut buchen (bestehende Buchung „Bestätigt"/„Aktiv") | Ablehnung mit klarer Meldung — sowohl im Formular als auch bei direktem API-Aufruf |
| B3 | Kompletter Status-Durchlauf Anfrage → … → Abgeschlossen | Nur gültige Übergänge als Buttons; „Aktiv" setzt Fahrzeug auf „vermietet", „Zurückgegeben" auf „verfügbar" |
| B4 | Stornierung aus verschiedenen Status | Jederzeit möglich; blockiert das Fahrzeug nicht weiter |
| B5 | E-Mail-Extraktion: Beispiel-E-Mail einfügen, extrahieren | Name, Kontaktdaten, Fahrzeugtyp, Zeitraum, Ort korrekt vorbefüllt (mit und ohne konfigurierten KI-Schlüssel — Fallback liefert dieselbe Struktur) |
| B6 | Preisfaktoren: Buchung im Sommer / mit Wochenende / ≥ 7 Tage | Faktoren erscheinen einzeln in der Aufschlüsselung, Gesamtpreis multiplikativ korrekt |
| B7 | Realtime: Buchung in zweitem Browserfenster ändern | Buchungsliste aktualisiert sich ohne manuelles Neuladen |
2.6 Dokumente (Angebot / Auftragsbestätigung)
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| D1 | Buchung im Status „Angebot": PDF herunterladen | Korrektes Angebots-PDF (Kunde, Fahrzeug, Zeitraum, netto/MwSt./brutto, 14-Tage-Gültigkeit, Firmen-Absender) |
| D2 | „Per E-Mail senden" ohne konfigurierten Versanddienst | Erfolgs-Toast mit Simulationshinweis; Server-Log enthält Empfänger, Betreff, Anhang |
| D3 | Status auf „Bestätigt" setzen | Angebots-Button verschwindet, Auftragsbestätigung erscheint; bleibt bis „Abgeschlossen" abrufbar |
| D4 | Buchungsdaten ändern, PDF erneut abrufen | PDF zeigt aktuelle Werte (kein Caching bei Angebot/AB) |
2.7 Übergabe / Rückgabe & Schadensmeldungen
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| U1 | Ausgabe protokollieren (km, Tank, Zustand, Gegenstände-Checkliste) | Protokoll gespeichert, druckbare Ansicht öffnet korrekt |
| U2 | 3+ Fotos gleichzeitig auswählen | Jedes Foto eigener Fortschritt (Upload → Analyse → Ergebnis), Reihenfolge-unabhängig; Formular bleibt bedienbar |
| U3 | Speichern-Versuch während Fotos noch verarbeitet werden | Button deaktiviert mit Hinweis; nach Abschluss aller Fotos aktiv |
| U4 | Rückgabe mit Schadensfoto | KI-Analysetext am Foto gespeichert und am Protokoll sichtbar |
| U5 | Standalone-Schadensmeldung am Fahrzeug (ohne Buchung) | Meldung mit Fotos + Analyse erscheint am Fahrzeug; Fahrzeugstatus unverändert, weiterhin buchbar |
2.8 Rechnungen
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| RE1 | Rechnung aus abgeschlossener Buchung erzeugen | Fortlaufende Nummer, korrekte Netto/MwSt./Brutto-Berechnung (19 %), Fälligkeitsdatum gesetzt |
| RE2 | Statusübergänge Entwurf → Versendet → Bezahlt; Storno | Nur gültige Übergänge angeboten |
| RE3 | PDF-Download, E-Mail-Versand | Korrektes PDF; Versand bzw. Simulation wie bei D2 |
| RE4 | Versendete Rechnung mit überschrittenem Fälligkeitsdatum | Als überfällig gekennzeichnet |
2.9 Werkstatt-Workflow
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| W1 | „In Werkstatt geben" mit Grund (als Mitarbeiter/Admin) | Auftrag „Offen" angelegt; Fahrzeugstatus sofort „in Wartung" |
| W2 | Login als Werkstatt-Konto | Startseite = Werkstatt-Dashboard; Seitenleiste zeigt nur erlaubte Bereiche |
| W3 | Auftrag annehmen → Notiz eintragen → abschließen | Statuskette Offen → In Bearbeitung → Abgeschlossen; Fahrzeugstatus automatisch zurück auf „verfügbar" |
| W4 | Werkstatt-Konto ruft /vehicles, /customers, /bookings direkt auf | Kein Zugriff (Umleitung/403) — auch per direktem API-Aufruf |
| W5 | Fahrzeugdetailseite (als Mitarbeiter) bei laufendem Auftrag | Direkter Link zum Werkstattauftrag sichtbar |
2.10 Versicherungsmodul
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| V1 | Police anlegen (Anbieter, Nr., Typ, Zeitraum) mit PDF-Upload | Police erscheint am Fahrzeug; PDF nur mit Leserecht abrufbar |
| V2 | Zweite Police mit späterem Zeitraum anlegen | Historie bleibt erhalten (keine Überschreibung) |
| V3 | Police läuft bald ab / ist abgelaufen | Warnung auf Fahrzeugdetailseite und Dashboard |
| V4 | Ungültiger Zeitraum (bis < von) | Ablehnung (Constraint) |
| V5 | Schadensfall anlegen, Status Offen → In Bearbeitung → Abgeschlossen | Statuskette funktioniert; Schadensfotos lassen sich zuordnen |
| V6 | Werkstatt-Konto greift auf Policen zu | Kein Zugriff (kein insurance-Recht) |
2.11 Berichte
| Nr. | Testfall | Erwartetes Ergebnis |
|---|
| RP1 | /reports öffnen | Alle Diagramme laden fehlerfrei (Umsatzverlauf, Auslastung, Top-Fahrzeuge/-Kunden, Funnel) |
| RP2 | Kennzahlen-Karten | Werte plausibel und konsistent mit /invoices und /bookings |
| RP3 | Neue Buchung + Rechnung anlegen, Berichte neu laden | Zahlen spiegeln die neuen Daten wider |
2.12 End-to-End-Regressionstest
Abschließender Gesamtdurchlauf über alle Module:
- Fahrzeug anlegen → Kunde anlegen → Buchung (Anfrage) → Angebot (+ PDF/E-Mail) → Bestätigt (+ Auftragsbestätigung) → Aktiv (Ausgabe mit Fotos) → Rückgabe (mit Schadensfoto + KI-Analyse) → Abgeschlossen → Rechnung erzeugen → versenden → als bezahlt markieren.
- Bei jedem Statuswechsel: korrekte Buttons, korrekte Toasts, korrekter Fahrzeugstatus.
- Danach: Berichte spiegeln die neue Buchung/Rechnung wider; Fahrzeug wieder „verfügbar".
3. Bekannte Einschränkungen zum Testzeitpunkt
- E-Mail-Versand im Demo-Betrieb simuliert (kein
RESEND_API_KEY hinterlegt) — Testfälle D2/RE3 prüfen den Simulationspfad.
- KI-Analysequalität hängt vom konfigurierten Gemini-Schlüssel ab; ohne Schlüssel greift der deterministische Mock (Struktur identisch, Inhalte statisch bzw. heuristisch).
- Kundenportal bewusst nicht vorhanden (Produktentscheidung) — ein auftauchender
/portal-Pfad wäre eine Regression.