Alle Dokumente

FleetFlow — Testdokumentation

Testkonzept, Testebenen und manueller Testplan

ProjektFleetFlow — Flottenmanagement für Autovermietungen
Stand30.07.2026 (main, inkl. Versicherungsmodul)
ErgänzendTESTING.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:

EbeneWerkzeug / VorgehenPrüft
Statische Prüfungnpx tsc --noEmit (TypeScript strict), npm run lint (ESLint)Typfehler, Stilverstöße, tote Importe
Build-Prüfungnpm run buildFehlerfreier Produktionsbuild, korrekte Routen-Tabelle
DatenverifikationDirekte SQL-Abfragen gegen die (Remote-)Datenbank nach jeder MigrationErwartete Struktur, Constraints, Seed-Daten, Idempotenz der Migrationen
Isolierte FunktionstestsDirekter Aufruf zentraler Funktionen mit konkreten BeispieldatenPreisberechnung, Verfügbarkeitsprüfung, Auslastungs-/Umsatzaggregation, Warn-Schwellwerte, PDF-Rendering, KI-Fallbacks
Sicherheits-/NegativtestsEnd-to-End-Tests mit Wegwerf-Testkonten, direkte API-Aufrufe ohne BerechtigungRLS-Policies, 403-Verhalten, Anti-Privilege-Escalation
Manuelle UI-TestsTestplan in Abschnitt 2, Klickpfade je RolleTatsä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.TestfallErwartetes Ergebnis
A1Login mit korrektem Passwort, Konto ohne eingerichteten FaktorAutomatische Weiterleitung zur 2FA-Einrichtung (QR-Code); ohne Abschluss kein Zugriff auf interne Seiten
A2QR-Code mit Authenticator-App scannen, gültigen Code eingebenEinrichtung erfolgreich, Weiterleitung in die App
A3Erneuter Login (Faktor vorhanden)Nach Passwort folgt Code-Abfrage; falscher Code → Fehlermeldung, korrekter Code → Zugriff
A4Direkter Aufruf einer internen URL (z. B. /vehicles) ohne bestandenen zweiten FaktorUmleitung zur Code-Abfrage bzw. Einrichtung — kein Vorbeikommen per Lesezeichen
A5Aufruf von /mfa/enroll mit bereits voll authentifizierter SessionUmleitung in die App (kein erneutes Enrollment)
A6Faktor unter Einstellungen → Sicherheit zurücksetzenBeim nächsten Seitenaufruf erzwungene Neueinrichtung per QR-Code
A7Registrierung aufrufen, obwohl bereits eine Firma eingerichtet istAblehnung mit Hinweis, dass das System bereits eingerichtet ist (HTTP 409)

2.2 Rollen- und Berechtigungssystem

Nr.TestfallErwartetes Ergebnis
R1Login mit Rolle ohne Schreibrecht auf einen BereichBearbeiten-/Neu-Buttons erscheinen nicht; direkter Aufruf der Bearbeiten-URL leitet zur Detailseite zurück
R2Direkter API-Aufruf ohne Recht (Browser-Konsole, z. B. DELETE /api/vehicles/[id])Klare Fehlermeldung mit HTTP 403 — keine stille leere Antwort, keine Ausführung
R3Neue Rolle anlegen, Berechtigungsmatrix einstellen, Testkonto zuweisen, damit einloggenExakt die eingestellten Rechte greifen (Navigation, Buttons, API)
R4Versuch, Grundrollen (admin/mitarbeiter/kunde) umzubenennen oder zu löschenWird verweigert
R5Rolle eines bestehenden Kontos in der Mitarbeiterliste ändernWirkt beim nächsten Seitenaufruf des Betroffenen
R6Versuch, die eigene Rolle ohne Benutzerverwaltungs-Recht zu ändern (direkt per Datenbank-API/Anon-Key)Wird durch Datenbank-Trigger abgelehnt
R7Bereich ohne Leserecht: Menüpunkt sichtbar?Nein — aus der Seitenleiste ausgeblendet

2.3 Fahrzeuge

Nr.TestfallErwartetes Ergebnis
F1Fahrzeug anlegen mit allen StammdatenErfolgs-Toast, Fahrzeug erscheint in Liste und auf der Karte (bei GPS-Koordinaten)
F2Filtern nach Status/Typ, Freitextsuche (Kennzeichen/Marke/Modell/VIN), KombinationErgebnisse korrekt (UND-Verknüpfung), URL-Parameter gesetzt, Suche debounced
F3> 50 Fahrzeuge vorhandenPagination erscheint („Zeige 1–50 von N"); Filterwechsel springt auf Seite 1
F4HU/Service-Termin in < 30 Tagen bzw. überschrittenWarnung auf Liste, Detailseite und Dashboard; Buchung bleibt möglich
F5Aufbereitung: Intervall in Einstellungen ändern, letzte_aufbereitung zurückdatierenWarnstufen ok/bald fällig/überfällig entsprechend Intervall; „Aufbereitung abgeschlossen" setzt zurück
F6Fahrzeug löschen als Rolle ohne LöschrechtButton deaktiviert mit Tooltip; direkter API-Aufruf → 403

2.4 Kunden

Nr.TestfallErwartetes Ergebnis
K1Kundentyp im Formular zwischen Privat und Firma umschaltenFelder wechseln korrekt (Vor-/Nachname ↔ Firmenname/Ansprechpartner/USt-IdNr.)
K2Firmenkunde speichern und Detailseite öffnenFirma, Ansprechpartner, USt-IdNr. werden angezeigt
K3Suche nach Name/Firma/E-Mail/Telefon/OrtTreffer korrekt, serverseitig über den gesamten Bestand
K4Abgelaufener Führerschein beim PrivatkundenWarnung auf der Kundendetailseite
K5KundendetailseiteVollständige Buchungshistorie sichtbar

2.5 Buchungen

Nr.TestfallErwartetes Ergebnis
B1Buchung anlegen (Fahrzeug, Kunde, Zeitraum)Preisvorschau mit Faktor-Aufschlüsselung; Speichern mit Toast
B2Fahrzeug im selben Zeitraum erneut buchen (bestehende Buchung „Bestätigt"/„Aktiv")Ablehnung mit klarer Meldung — sowohl im Formular als auch bei direktem API-Aufruf
B3Kompletter Status-Durchlauf Anfrage → … → AbgeschlossenNur gültige Übergänge als Buttons; „Aktiv" setzt Fahrzeug auf „vermietet", „Zurückgegeben" auf „verfügbar"
B4Stornierung aus verschiedenen StatusJederzeit möglich; blockiert das Fahrzeug nicht weiter
B5E-Mail-Extraktion: Beispiel-E-Mail einfügen, extrahierenName, Kontaktdaten, Fahrzeugtyp, Zeitraum, Ort korrekt vorbefüllt (mit und ohne konfigurierten KI-Schlüssel — Fallback liefert dieselbe Struktur)
B6Preisfaktoren: Buchung im Sommer / mit Wochenende / ≥ 7 TageFaktoren erscheinen einzeln in der Aufschlüsselung, Gesamtpreis multiplikativ korrekt
B7Realtime: Buchung in zweitem Browserfenster ändernBuchungsliste aktualisiert sich ohne manuelles Neuladen

2.6 Dokumente (Angebot / Auftragsbestätigung)

Nr.TestfallErwartetes Ergebnis
D1Buchung im Status „Angebot": PDF herunterladenKorrektes Angebots-PDF (Kunde, Fahrzeug, Zeitraum, netto/MwSt./brutto, 14-Tage-Gültigkeit, Firmen-Absender)
D2„Per E-Mail senden" ohne konfigurierten VersanddienstErfolgs-Toast mit Simulationshinweis; Server-Log enthält Empfänger, Betreff, Anhang
D3Status auf „Bestätigt" setzenAngebots-Button verschwindet, Auftragsbestätigung erscheint; bleibt bis „Abgeschlossen" abrufbar
D4Buchungsdaten ändern, PDF erneut abrufenPDF zeigt aktuelle Werte (kein Caching bei Angebot/AB)

2.7 Übergabe / Rückgabe & Schadensmeldungen

Nr.TestfallErwartetes Ergebnis
U1Ausgabe protokollieren (km, Tank, Zustand, Gegenstände-Checkliste)Protokoll gespeichert, druckbare Ansicht öffnet korrekt
U23+ Fotos gleichzeitig auswählenJedes Foto eigener Fortschritt (Upload → Analyse → Ergebnis), Reihenfolge-unabhängig; Formular bleibt bedienbar
U3Speichern-Versuch während Fotos noch verarbeitet werdenButton deaktiviert mit Hinweis; nach Abschluss aller Fotos aktiv
U4Rückgabe mit SchadensfotoKI-Analysetext am Foto gespeichert und am Protokoll sichtbar
U5Standalone-Schadensmeldung am Fahrzeug (ohne Buchung)Meldung mit Fotos + Analyse erscheint am Fahrzeug; Fahrzeugstatus unverändert, weiterhin buchbar

2.8 Rechnungen

Nr.TestfallErwartetes Ergebnis
RE1Rechnung aus abgeschlossener Buchung erzeugenFortlaufende Nummer, korrekte Netto/MwSt./Brutto-Berechnung (19 %), Fälligkeitsdatum gesetzt
RE2Statusübergänge Entwurf → Versendet → Bezahlt; StornoNur gültige Übergänge angeboten
RE3PDF-Download, E-Mail-VersandKorrektes PDF; Versand bzw. Simulation wie bei D2
RE4Versendete Rechnung mit überschrittenem FälligkeitsdatumAls überfällig gekennzeichnet

2.9 Werkstatt-Workflow

Nr.TestfallErwartetes Ergebnis
W1„In Werkstatt geben" mit Grund (als Mitarbeiter/Admin)Auftrag „Offen" angelegt; Fahrzeugstatus sofort „in Wartung"
W2Login als Werkstatt-KontoStartseite = Werkstatt-Dashboard; Seitenleiste zeigt nur erlaubte Bereiche
W3Auftrag annehmen → Notiz eintragen → abschließenStatuskette Offen → In Bearbeitung → Abgeschlossen; Fahrzeugstatus automatisch zurück auf „verfügbar"
W4Werkstatt-Konto ruft /vehicles, /customers, /bookings direkt aufKein Zugriff (Umleitung/403) — auch per direktem API-Aufruf
W5Fahrzeugdetailseite (als Mitarbeiter) bei laufendem AuftragDirekter Link zum Werkstattauftrag sichtbar

2.10 Versicherungsmodul

Nr.TestfallErwartetes Ergebnis
V1Police anlegen (Anbieter, Nr., Typ, Zeitraum) mit PDF-UploadPolice erscheint am Fahrzeug; PDF nur mit Leserecht abrufbar
V2Zweite Police mit späterem Zeitraum anlegenHistorie bleibt erhalten (keine Überschreibung)
V3Police läuft bald ab / ist abgelaufenWarnung auf Fahrzeugdetailseite und Dashboard
V4Ungültiger Zeitraum (bis < von)Ablehnung (Constraint)
V5Schadensfall anlegen, Status Offen → In Bearbeitung → AbgeschlossenStatuskette funktioniert; Schadensfotos lassen sich zuordnen
V6Werkstatt-Konto greift auf Policen zuKein Zugriff (kein insurance-Recht)

2.11 Berichte

Nr.TestfallErwartetes Ergebnis
RP1/reports öffnenAlle Diagramme laden fehlerfrei (Umsatzverlauf, Auslastung, Top-Fahrzeuge/-Kunden, Funnel)
RP2Kennzahlen-KartenWerte plausibel und konsistent mit /invoices und /bookings
RP3Neue Buchung + Rechnung anlegen, Berichte neu ladenZahlen spiegeln die neuen Daten wider

2.12 End-to-End-Regressionstest

Abschließender Gesamtdurchlauf über alle Module:

  1. 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.
  2. Bei jedem Statuswechsel: korrekte Buttons, korrekte Toasts, korrekter Fahrzeugstatus.
  3. 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.