Zum Inhalt

E2E-Tests

End-to-End-Tests (E2E) prüfen komplette Nutzer-Workflows im echten Browser — vom Klick über Frontend und Backend bis in die Datenbank. Sie stehen an der Spitze der Testpyramide: am wenigsten zahlreich, am langsamsten, aber am realistischsten. E2E-Tests nutzen Selenium WebDriver mit dem Page-Object-Pattern und erzeugen Markdown-Testprotokolle mit Screenshots (interne Referenz: NFR-008).

Was diese Stufe prüft

  • Durchgängige Abläufe: z. B. Login → Datensatz anlegen → speichern → wiederfinden, quer durch alle Schichten.
  • Reales Zusammenspiel: echter Browser, echtes Frontend (nginx), echtes Backend, echte Datenbank.

Getestete Bereiche im Überblick

E2E-Suiten sind nach Anforderung (REQ) organisiert. Thematisch gebündelt:

Bereich Beispiel-Workflows Umfang
Stammdaten & Lebenszyklus Arten/Sorten, Phasensteuerung, Pflanzdurchlauf umfangreich
Bewässerung & Düngung Nährlösung, Feeding, Tankmanagement mittel
Aufgaben & Pflege Task-Queue, Pflege-Dashboard, Erinnerungen mittel
Ernte & Nachernte Erntereife, Ernteliste, Post-Harvest mittel
Pflanzenschutz Schädlinge/Krankheiten, Foto-Erkennung, Diagnose mittel
Plattform Anmeldung, Mandanten, Datenschutz, Light-Modus umfangreich
Weitere Dashboard, Kalender, Onboarding, Mischkultur, Notifications, KI-Assistent, Druckansichten mittel

Kuratierte Testfall-Spezifikationen

Detaillierte, nummerierte Testfälle liegen als Markdown-Dokumente unter spec/e2e-testcases/ (TC-REQ-*, TC-NFR-*) samt COVERAGE-REPORT.md. Sie beschreiben je Anforderung Vorbedingungen, Schritte und erwartete Ergebnisse.

Werkzeug & Ort

Wert
Werkzeug Selenium WebDriver, pytest, Page-Object-Pattern
Ort tests/e2e/
Locator data-testid-Attribute (nie CSS-Struktur)

CI: Smoke-Gate pro PR + Nightly-Volllauf

Die Suite läuft auch in GitHub Actions — mit demselben Docker-Compose-Stack wie lokal: Der Workflow e2e-smoke führt das schnelle Smoke-Profil bei jedem Pull Request und bei Pushes nach develop aus. Er war von ADR-011 bis zum 2026-07-29 ein Pflicht-Check auf develop und ist seither beratend: Er läuft und meldet weiterhin bei jedem Pull Request, blockiert den Merge aber nicht mehr — lies ihn, bevor du mergst. Grund für die Rücknahme war die Merge-Latenz von rund 11 Minuten pro Lauf; die Abdeckung trägt jetzt der nächtliche Vollmatrix-Lauf. Ob die Suite tatsächlich läuft, entscheidet weiterhin ein Job im Workflow selbst und nicht ein Pfadfilter am Trigger: Ein per Pfadfilter übersprungener Pflicht-Workflow meldet nie ein Ergebnis und blockiert den Pull Request dauerhaft — diese Konstruktion bleibt bestehen, damit sich der Check jederzeit wieder scharf schalten lässt. Der Workflow e2e-nightly fährt nächtlich die vollständige Suite als Matrix über die Compose-Profile light, full, mobile, tablet und full-mobile; ein roter Lauf legt kein GitHub-Issue mehr an — Lauf-Status, gerenderter Check-Run je Profil und die Artifacts enthalten alles, was das automatische Issue nur wiederholt hat. Testprotokoll, Screenshots und Container-Logs hängen als Workflow-Artifacts an jedem Lauf.

CI-Testberichte

Jeder Testlauf schreibt zusätzlich zu Protokoll und Screenshots einen JUnit-XML-Report (junit-<profil>.xml), der die TC-ID jedes Testfalls als tc_id-Property mitführt. In GitHub Actions rendert der Workflow e2e-smoke (pro Pull Request) sowie jedes Profil im e2e-nightly-Workflow diesen Report zusätzlich per dorny/test-reporter als GitHub-Check-Run und als Tabelle in der Job-Summary — mit der konkreten Fehlermeldung (Assertion-Text plus kurzer Traceback) je fehlgeschlagenem Test, statt nur einem grünen/roten Gesamtstatus.

Fork-Pull-Requests: kein gerenderter Check

Bei Pull Requests aus Forks kann der Render-Schritt mit dem eingeschränkten GITHUB_TOKEN keinen Check-Run anlegen und wird übersprungen (continue-on-error). e2e-smoke erkennt das und schreibt in diesem Fall die Ergebnisübersicht samt fehlgeschlagener Tests aus dem Testprotokoll in die Job-Summary — sonst steht die Job-Summary nur als Zeiger auf das Artifact, damit dieselben Zahlen nicht doppelt erscheinen. Das junit-*.xml-Artifact gibt es in beiden Fällen.

Der gerenderte Check-Run ist eine CI-Ergänzung — er ersetzt nicht das Markdown-Testprotokoll (protokoll.md) mit den eingebetteten Screenshots, das weiterhin das menschenlesbare Nachweisdokument bleibt (NFR-008 §4.4).

Ausführen

# Lokal gegen laufende App (Chrome headless, localhost:5173)
pytest tests/e2e/ -v

# Dedizierter, isolierter Docker-Stack (App + Selenium Grid)
./scripts/run-e2e.sh                    # volle light-Suite
./scripts/run-e2e.sh --smoke            # Smoke-Suite (~7 min)
./scripts/run-e2e.sh --profile mobile   # ein einzelnes Compose-Profil

Reports und Screenshots landen unter test-reports/e2e/<timestamp>/, darunter auch der JUnit-XML-Report — siehe CI-Testberichte. Der vollständige Stack, die Fixtures und das Protokoll-Format stehen im Testkonzept → E2E-Tests.

Testfall-Nachverfolgbarkeit (Pflicht-Gate)

Jeder E2E-Test muss benennen, welchen spezifizierten Testfall er prüft — als @TC-<id>-Tag im Gherkin-Szenario oder als TC-ID im Docstring des klassischen Tests. scripts/check_bdd_traceability.py prüft das maschinell und läuft als pre-commit-Hook im required static-Job:

task test:e2e:traceability                        # Exit 0 / 1, kein Stack nötig
task test:e2e:traceability -- --list-unimplemented # + Fälle ohne Test

Vier Defektklassen, je zwei pro Kanal:

Kanal Defekt
Gherkin Tag, den kein Testfall-Dokument deklariert
Gherkin Szenario ohne Tag
Docstring TC-ID, die kein Testfall-Dokument deklariert
Docstring Testfunktion ohne TC-ID

Die Rückrichtung ist kein Defekt: ein spezifizierter Testfall ohne Test ist noch nicht automatisiert und wird nur gezählt.

Der Vorschlag „did you mean …?“ ist keine Übereinstimmung

Findet der Check eine unauflösbare ID, schlägt er die nächstliegende bekannte ID vor. Das ist String-Nachbarschaft, keine fachliche Übereinstimmung. TC-REQ-027-001TC-027-001 sieht wie ein Tippfehler aus, beschreibt aber anderes Verhalten. In #839 wurden drei solcher Vorschläge gegen den Spec-Text geprüft — alle drei waren falsch.

Beschreibt kein Testfall das geprüfte Verhalten, ist das ehrliche Ergebnis ein neuer Testfall in spec/e2e-testcases/, keine erzwungene Zuordnung. Eine falsche Zuordnung ist schlimmer als keine: sie behauptet Abdeckung, die es nicht gibt. In #839 brauchten 66 von 99 Fällen genau das.

Konventionen

  • Jedes Page Object erbt von BasePage und kapselt genau einen Bildschirm.
  • Elemente ausschließlich über data-testid-Locator ansprechen — nie über brüchige CSS-Pfade.
  • Screenshots an fachlichen Checkpoints explizit aufnehmen; bei Fehlern werden sie automatisch erfasst.
  • Jeder neue Test nennt seine TC-ID — siehe Testfall-Nachverfolgbarkeit.