Testphasen-Plan ergänzen (Phase 0-5 + Phase S Satelliten-PoC, Excel-Import-Mapping)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L85hmKbvX7Cqkq47KnQhFt
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
# Testphasen – MABEA V1
|
||||
|
||||
Bezug: [[22_testkonzept]], [[18_version_1]], [[02_prozess_kontrolle]], [[03_fehlbestandsmanagement]], [[04_mindermengen]], [[05_rollen_rechte]], [[17_mobile_offline]], [[21_api]].
|
||||
|
||||
Grundprinzip: Tests werden **phasenweise** aufgebaut, parallel zur Implementierung – nicht als Block am Ende. Jede Phase hat Einstiegs- und Abnahmekriterien. Der Satelliten-Betrieb (Karte 13) ist bewusst **nicht** Teil der V1-Testphasen, sondern eigene spätere Phase S (Roadmap).
|
||||
|
||||
## Phase 0 – Testinfrastruktur (vor erstem Feature-Code)
|
||||
|
||||
**Ziel:** Gerüst steht, bevor Logik entsteht – verhindert „Tests schreiben wir später".
|
||||
|
||||
- pytest + pytest-asyncio + httpx (AsyncClient für FastAPI) im Projekt
|
||||
- pytest-cov mit Regressions-Gate: `--cov-fail-under=50` als Startwert in `pytest.ini` (Erfahrungswert: lieber niedrig starten und hochschrauben als gar kein Gate)
|
||||
- Separate **Test-Datenbank** (eigene PostgreSQL-Datenbank, Schema via Alembic-Migrationen aufgesetzt, nie gegen Dev-/Produktiv-DB)
|
||||
- Test-Fixtures: frische DB pro Testklasse (Transaction-Rollback oder Drop/Create), Standard-Stammdaten-Set (1 Bereich, 2 Standorte, 3 Objekttypen, ~10 Materialien aller 3 Typen, 1 Vorlage mit Positionen, 2 Objekte, 4 Benutzer = 1 je Rolle)
|
||||
- CI-Job (Gitea Actions): install → migrate → pytest → Coverage-Report; Blocker bei Rot
|
||||
|
||||
**Abnahmekriterium:** `pytest` läuft grün (auch wenn erst 1 Smoke-Test existiert), CI schlägt bei Testfehler fehl.
|
||||
|
||||
## Phase 1 – Domänenlogik (Unit-Tests, keine API, keine UI)
|
||||
|
||||
**Ziel:** Die fachlichen Leitplanken sind bewiesen, bevor irgendein Endpoint existiert. Reine Python-Tests gegen den Service-Layer (Prompt 19 Punkt 2), DB über Fixtures.
|
||||
|
||||
Kritischste Regeln zuerst (aus `reihenfolge.md` und Prompt 03/04):
|
||||
|
||||
| # | Test | Herkunft |
|
||||
|---|------|----------|
|
||||
| U1 | Fehlbestand entsteht automatisch bei Ist < Soll | Prompt 02.3 |
|
||||
| U2 | Mindermengen-Genehmigung ändert NIEMALS Ist-Menge und setzt Fehlbestand NIEMALS auf erledigt | Leitplanke, Prompt 04.1 |
|
||||
| U3 | Fehlbestand → erledigt AUSSCHLIESSLICH wenn Ist = Soll (nie manuell) | Prompt 03.3 |
|
||||
| U4 | Sofort-Nachfüllung in Kontrolle: Fehlbestand entsteht + wird erledigt, 2 Historieneinträge | Karte 07 |
|
||||
| U5 | Teilnachfüllung: Status `nachgefuellt_teilweise`, Fehlmenge reduziert, zählt weiter als offen | Prompt 03/12 |
|
||||
| U6 | Genehmigung läuft bei nächster Kontrolle des Objekts automatisch ab | Karte 08, Prompt 04.4 |
|
||||
| U7 | Genehmigung + Behebung vor nächster Kontrolle → beides gemeinsam beendet | Prompt 04.4 |
|
||||
| U8 | Soll-Auflösung: Override auf Objektposition schlägt Vorlagenwert; Vorlagenänderung wirkt nur auf Positionen ohne Override | Prompt 10 |
|
||||
| U9 | Duplizieren: Struktur/Soll ja, Ist/SN/Chargen/Fehlbestände/Historie nein, neuer Code | Prompt 09 |
|
||||
| U10 | Vorlagenänderung erzeugt neue Version, alte Version bleibt lesbar (Snapshot-Historie) | Prompt 08 |
|
||||
| U11 | Kontrolle abschließen mit unbestätigten Positionen → Fehler | Prompt 16.1 |
|
||||
| U12 | Abgebrochene Kontrolle: keine Ist-Übernahme, kein Fehlbestand, Objekt bleibt unkontrolliert | Prompt 16.6 |
|
||||
| U13 | Überbestand (Ist > Soll): protokolliert, aber KEIN Fehlbestand | Prompt 02.4 |
|
||||
| U14 | Historie ist append-only: jeder fachliche Schritt erzeugt Eintrag mit wer/wann/alt→neu | Prompt 13 |
|
||||
|
||||
**Einstiegskriterium:** Phase 0 fertig.
|
||||
**Abnahmekriterium:** U1–U14 grün, Coverage Service-Layer ≥ 80 % (Domänenlogik ist der sicherheitskritische Kern).
|
||||
|
||||
## Phase 2 – API-Integrationstests (HTTP gegen Test-DB)
|
||||
|
||||
**Ziel:** Jeder Endpoint aus Prompt 21 verhält sich spezifikationsgemäß, inkl. Rollenmatrix und Fehlerfälle.
|
||||
|
||||
- **Auth:** Login ok/falsch (401), Token abgelaufen, `auth/me` liefert korrekte Rollen
|
||||
- **Rollenmatrix (Prompt 05):** parametrisierter Test – jede Rolle × jede kritische Aktion → erwarteter Status (200er/403). Das ist EIN Test mit Tabelle, deckt Matrix vollständig ab
|
||||
- **Fehlerfälle aus Prompt 21.9:** Genehmigung ohne Begründung → 422; Genehmigung durch Mitarbeiter → 403; Abschluss mit offenen Positionen → 409 + Liste; Code-Duplikat beim Anlegen/Duplizieren → 409
|
||||
- **Idempotenz PUT Kontrollposition:** derselbe PUT zweimal gesendet → identischer Endzustand, kein doppelter Fehlbestand (Vorbereitung Prompt 17)
|
||||
- **Zuständigkeitsfilter (Karte 04):** Verantwortlicher sieht nur Fehlbestände seines Bereichs, Administration alles
|
||||
- **Objekt-Sperre (Prompt 02.8):** Kontrolle auf Objekt A aktiv → zweiter Benutzer bekommt „wird kontrolliert von …", Übernahme erzeugt Historieneintrag; parallele Kontrollen auf Objekt B bleiben möglich
|
||||
- **Admin-API (7a):** Benutzer/Zuständigkeiten/Kontrollverantwortung anlegen, ändern, löschen
|
||||
|
||||
**Einstiegskriterium:** Phase 1 grün.
|
||||
**Abnahmekriterium:** alle Endpunkte aus Prompt 21 durch Tests abgedeckt, Gesamt-Coverage ≥ 50 % (Gate greift).
|
||||
|
||||
## Phase 3 – Prozess-Szenarien (E2E über API, komplette fachliche Ketten)
|
||||
|
||||
**Ziel:** Die 17 Testfälle aus [[22_testkonzept]] als durchspielbare Szenarien – hier wird bewiesen, dass die Einzelteile zusammenwirken.
|
||||
|
||||
- S1–S17 = exakt die Testfälle 1–17 aus Prompt 22 (Normalfall, Fehlbestand, Sofort-Nachfüllung, Nachfüllung später, Teilnachfüllung, Dauer-offen, Genehmigung, Ablauf Genehmigung ×2, Ablaufdatum, Duplizieren, Override, Vorlagenänderung mit Override, Rollenmatrix, Historie-Kette, Kurzzeit-Netzausfall, Abbruch)
|
||||
- Besonderheit S15 (Historie-Kette): komplette Kette aus Prompt 13.3 durchlaufen und Reihenfolge + Referenzen aller Historieneinträge prüfen
|
||||
- Besonderheit S16 (Netzausfall): clientseitig simuliert – PUT zweimal absetzen bzw. verzögert, Server-Verhalten muss identisch sein
|
||||
|
||||
**Einstiegskriterium:** Phase 2 grün.
|
||||
**Abnahmekriterium:** S1–S17 grün, zweimal reproduzierbar (kein Flaky).
|
||||
|
||||
## Phase 4 – Frontend/PWA-Tests
|
||||
|
||||
**Ziel:** Die Einsatzumfeld-Anforderungen (Prompt 11, 17) sind bewiesen.
|
||||
|
||||
- **Kurzzeit-Netzausfall:** Eingabe wird lokal gepuffert, nach Reconnect automatisch übertragen, Abschluss blockiert solange ungesendete Positionen existieren (Prompt 17.3) – Browser-Test mit Netzwerk-Throttling/Offline-Toggle (Playwright)
|
||||
- **Responsivität:** Kernscreens (Screen 1–6) auf PC + Tablet + Smartphone-Viewport bedienbar, Touch-Ziele groß genug
|
||||
- **Fortschrittsanzeige + Gerätewechsel:** Kontrolle auf Gerät 1 begonnen, auf Gerät 2 fortgesetzt (login-/objektgebunden, Karte 06)
|
||||
- **Statusfarben/Markierungen:** genehmigte Mindermenge, individuelle Abweichung, Ablaufdatum-Warnung sichtbar unterscheidbar
|
||||
- **Manuelle Explorations-Session:** 2–3 Praktiker aus dem Rettungsdienst klicken ohne Anleitung durch eine Kontrolle – Beobachtung dokumentieren (UX-Fallen)
|
||||
|
||||
**Einstiegskriterium:** Phase 3 grün, PWA bedienbar auf Test-Deployment.
|
||||
**Abnahmekriterium:** Netzausfall-Test grün, keine kritischen UX-Befunde offen.
|
||||
|
||||
## Phase 5 – Pilotphase mit Echtdaten (organisatorisch, kein Code-Test)
|
||||
|
||||
**Ziel:** Realitätsabgleich, bevor Papier abgeschaltet wird.
|
||||
|
||||
- Testdaten aus den **echten Excel-Listen** (Handball Rucksack.xlsx, Rettungsrucksack.xlsx, Rucksack PAX SEG.xlsx im Repo) als initiale Vorlagen/Materialstamm importieren (Mapping siehe Abschnitt „Excel-Import-Mapping" unten)
|
||||
- 1–2 Wochen **Parallelbetrieb**: Kontrolle digital UND Papier wie bisher, danach Abgleich (findet das System alles, was Papier fand?)
|
||||
- Dedizierte Übungskontrollen mit vorher verabredeten Abweichungen („versteckte Fehlmenge") – prüft, ob Mitarbeiter den digitalen Weg korrekt durchlaufen
|
||||
- E-Mail-Benachrichtigung (Karte 05) mit realem Mailserver verifizieren
|
||||
- Feedback-Runde → kleinteilige UI-Nachjustierung
|
||||
|
||||
**Einstiegskriterium:** Phase 4 grün, Echtdaten importiert, Test-Deployment erreichbar.
|
||||
**Abnahmekriterium (Go/No-Go für V1):** Parallelbetrieb ohne fachliche Diskrepanz, keine Datenverluste, Akzeptanz bei Pilotnutzern vorhanden.
|
||||
|
||||
## Excel-Import-Mapping (Detail zu Phase 5)
|
||||
|
||||
Grundlage: die drei bestehenden Listen im Repo (`Handball Rucksack.xlsx`, `Rettungsrucksack.xlsx`, `Rucksack PAX SEG.xlsx`), Struktur laut Ausgangsanalyse (Prompt 01): Fach-Überschriftzeile, darunter Zeilen mit Artikel/Menge/Artikelnummer, teils Seriennummer-Spalte.
|
||||
|
||||
### Mapping-Tabelle
|
||||
|
||||
| Excel-Spalte/Struktur | Ziel im Datenmodell (Prompt 06/20) | Hinweis |
|
||||
|---|---|---|
|
||||
| Datei selbst (z. B. „Handball Rucksack") | `objekttyp.name` + `beladungsvorlage.name` (z. B. „Rucksack Handball Standard") | Ein Import-Lauf pro Datei erzeugt einen Objekttyp + eine Vorlage Version 1 |
|
||||
| Fach-Überschriftzeile (z. B. „Fach 1") | `vorlagenposition.fach` | Freitext übernehmen wie in Excel geschrieben, keine Normalisierung nötig |
|
||||
| Artikel-Spalte | `material.name` (neu anlegen, falls Name noch nicht im Materialstamm existiert) | Abgleich über Artikelnummer, nicht über Namensgleichheit (Tippfehler-Gefahr) |
|
||||
| Artikelnummer-Spalte | `material.artikelnummer` | Primärer Abgleichsschlüssel beim Import: gleiche Artikelnummer über mehrere Listen hinweg → derselbe Materialstamm-Eintrag, nicht dubliziert anlegen |
|
||||
| Menge-Spalte | `vorlagenposition.sollmenge` | Numerisch parsen, Fehleinträge (z. B. „ca. 5") vor Import manuell bereinigen |
|
||||
| Seriennummer-Spalte (falls vorhanden) | Materialtyp-Erkennung: Vorhandensein einer SN-Spalte bei dieser Zeile → `material.materialtyp = 'geraet_sn'`, sonst `'standard'` | Ablaufdatum/Charge kommt in den bestehenden Listen nicht vor → für diese drei Listen entfällt Typ `ablauf_charge` beim Erstimport, wird später manuell ergänzt (z. B. Infusionssysteme) |
|
||||
| Einheit | nicht in Excel vorhanden | Beim Import Standardwert „Stück" setzen, danach manuell korrigieren wo nötig (z. B. „Paar", „Packung") |
|
||||
| Kategorie/Bereich | nicht in Excel vorhanden | Einmalig vor Import anlegen: 1 Bereich „Rettungsdienst/KatS", grobe Kategorie „Rucksäcke" für alle drei Objekttypen |
|
||||
|
||||
### Ablauf des Imports (Vorschlag, Umsetzung Phase 5)
|
||||
|
||||
1. Bereich + Kategorie einmalig anlegen (Administration, manuell oder Skript).
|
||||
2. Je Excel-Datei: Objekttyp + Beladungsvorlage Version 1 anlegen.
|
||||
3. Zeilen einlesen (stdlib `zipfile`/`xml.etree.ElementTree` wie bei der Erstanalyse, siehe Prompt 01 – kein `openpyxl` nötig): Fach, Artikel, Artikelnummer, Menge, optionale SN-Spalte.
|
||||
4. Je Zeile: Material anhand Artikelnummer suchen oder neu anlegen, dann Vorlagenposition mit Sollmenge und Fach erzeugen.
|
||||
5. Konkrete Objekte (z. B. „Rucksack Handball 12", „Rucksack Handball 17") werden NICHT aus Excel importiert (Excel enthält nur die Soll-Struktur, keine konkreten Instanzen) – Administration legt sie danach manuell an, je mit Code (Karte 10) und Vorlagen-Referenz.
|
||||
6. Erste Kontrolle je neu angelegtem Objekt erfasst den tatsächlichen Ist-Bestand (Objekte starten „nicht kontrolliert", analog Duplizieren-Regel Prompt 09) – dies IST der Übergang vom Papier- zum Digitalbetrieb (Prompt 23).
|
||||
|
||||
### Bekannte Lücken, vor Import zu klären
|
||||
- Einheiten pro Material sind in den Excel-Listen nicht erfasst – vor Import Liste durchgehen und einmalig ergänzen (einmaliger manueller Aufwand, keine Systemfrage).
|
||||
- Uneindeutige/fehlende Artikelnummern in den Quell-Listen (falls vorhanden) verhindern automatischen Abgleich – in diesen Fällen manuelle Zuordnung beim Import nötig.
|
||||
- Import-Skript selbst ist Code (Prompt-19-Deployment-Regel gilt: bei Umsetzung nur Skript-Datei erzeugen, Ausführung gegen Test-DB erst auf Zielsystem/Test-Deployment, nicht lokal).
|
||||
|
||||
## Regeln übergreifend
|
||||
|
||||
- **Kein Feature ohne Test:** jeder Endpoint/jede Domänenregel wird erst mit Test gemerged (CI-Gate).
|
||||
- **Leitplanke-Doppelschutz:** U2/U3 (Mindermenge ≠ erledigt) laufen zusätzlich als Phase-3-Szenario (S7) – bei Bruch dieser Regel sofortiger Release-Blocker.
|
||||
- **Coverage-Hochschraubung:** nach V1-Release Gate schrittweise 50 → 60 → 70 % erhöhen.
|
||||
- **Testdaten niemals Produktivdaten:** Pilotphase läuft auf Test-Deployment, echte Inbetriebnahme erst nach Go/No-Go.
|
||||
|
||||
## Phase S – Satelliten-Betrieb (spätere Erweiterung, NICHT V1)
|
||||
|
||||
Roadmap-Phase, erst nach stabiler V1. Eigener Testplan nötig, mindestens:
|
||||
|
||||
- **PoC mit zwei lokalen PostgreSQL-Instanzen** (Docker oder zwei Datenbanken): Objekt auslagern → Kontrolle + Fehlbestand + Nachfüllung + Genehmigung am „Satelliten" → zurücksyncen → Hauptserver-Stand vollständig und ohne Duplikate
|
||||
- Sync-Fälle 1–3 aus Prompt 20.10 einzeln beweisen (Insert neue Zeilen, Upsert Objektpositionen, Upsert Fehlbestand/Genehmigung)
|
||||
- Bestückungsregel testen: Objekt mit offenem Fehlbestand auslagern → am Satelliten nachfüllen → zurücksyncen → genau EIN Fehlbestand, erledigt
|
||||
- Schreibzugriff am Hauptserver auf ausgelagertes Objekt → muss abgelehnt werden
|
||||
- Offene Punkte aus Karte 13 vorher entscheiden: Pre-Sync-Check laufender Kontrollen, DB-Trigger für `zuletzt_geaendert_am`, Bestückungs-Details
|
||||
|
||||
## Referenzen
|
||||
Bezug: [[22_testkonzept]], [[18_version_1]], [[01_anforderungsanalyse]], [[09_duplizieren]], [[23_papieraloesung]], [[13_satelliten_server]]
|
||||
Reference in New Issue
Block a user