Die Browser-Tests legten ihre Konten, Kategorien und Buchungen bei jedem Lauf neu an, weggeräumt hat sie niemand: Zuletzt standen über dreitausend Zeilen Testdaten in der Datenbank – vierzig „E2E Bankprovision …“ hintereinander im Kategoriefilter, und kein Bildschirmfoto eines fehlgeschlagenen Tests war mehr zu gebrauchen. scripts/e2e-aufraeumen.php räumt weg, was am Testnutzer hängt – nicht, was nach Testdaten aussieht. Ein Namensmuster übersähe die Buchung „Supermarkt“ und träfe irgendwann etwas Echtes; die Fremdschlüssel dagegen sagen genau, was zu diesem Nutzer gehört, und nehmen über ihre Kaskaden auch die Zeilen ohne eigene benutzer_id mit. Der Nutzer selbst bleibt stehen, und er muss den Anzeigenamen tragen, den scripts/e2e-benutzer.php setzt: Wer E2E_USER versehentlich auf seinen eigenen Zugang stellt, bekommt einen Abbruch statt eines leeren Datenbestands. Aufgerufen wird es vor dem Lauf, nicht danach – ein abgebrochener Lauf hinterlässt sonst einen Bestand, an den niemand mehr denkt, und so bleiben die Daten des letzten Laufs bis zum nächsten für die Fehlersuche stehen. Das deckte auf, dass sieben Tests auf den Resten früherer Läufe standen: Die Auswertungen prüfen, dass ein Bericht eine Tabelle statt eines Platzhalters zeigt, das Cockpit, dass „Übrige Konten“ eine Ebene tiefer führt – Daten dafür legte keiner von ihnen an. scripts/e2e-grundbestand.php stellt deshalb einen festgelegten Bestand her, dessen Zuschnitte an genau diesen Tests hängen: mehr Konten als Vermoegensentwicklung::SERIEN, Buchungen in jedem Monat des laufenden Jahres, ein Vorjahr für den Vergleichsbericht, ein Depot mit Wertpapiergeschäft. Test 41 prüft jede dieser Grenzen einzeln und nennt den Test, der daran hängt. 87 E2E-Tests grün, in 1,3 statt 2,7 Minuten – die Listen rendern keine Tausenden Altzeilen mehr. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AQ57wQWZ4xKHcKmp26bzgr
122 lines
4.3 KiB
Markdown
122 lines
4.3 KiB
Markdown
# E2E-Tests
|
||
|
||
Browser-Tests mit Playwright, ausgeführt über das Projekt
|
||
[`e2e-runner`](../../../e2e-runner). Auf dem Host wird nichts installiert – der
|
||
Runner startet je Lauf einen frischen Container und räumt ihn danach weg.
|
||
|
||
## Voraussetzungen
|
||
|
||
Die Anwendung muss **vor** dem Testlauf laufen und vom Host erreichbar sein:
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
Einmalig den Testnutzer anlegen:
|
||
|
||
```bash
|
||
docker compose exec -u www-data php php scripts/e2e-benutzer.php
|
||
```
|
||
|
||
## Ausführen
|
||
|
||
```bash
|
||
tests/e2e/run.sh
|
||
```
|
||
|
||
Fehlt Docker, der Runner oder das Playwright-Image, wird mit Exit-Code 0
|
||
übersprungen statt fehlzuschlagen.
|
||
|
||
Abweichende Werte:
|
||
|
||
```bash
|
||
BASE_URL=http://host.docker.internal:8000 tests/e2e/run.sh
|
||
E2E_USER=e2e E2E_PASSWORD=geheim tests/e2e/run.sh
|
||
E2E_RUNNER_DIR=/pfad/zum/runner tests/e2e/run.sh
|
||
```
|
||
|
||
## Lockfile
|
||
|
||
`package.json` pinnt `@playwright/test` auf die Version des Runner-Images
|
||
(aktuell 1.61.1). Das Lockfile wird ohne lokale Node-Installation erzeugt:
|
||
|
||
```bash
|
||
docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD/tests/e2e":/work -w /work \
|
||
mcr.microsoft.com/playwright:v1.61.1-noble npm install --package-lock-only
|
||
```
|
||
|
||
## Welche Ebene wofür
|
||
|
||
Hierher gehört nur, was einen Browser braucht: Formularabläufe, Redirects,
|
||
gerenderte Views, JavaScript. Rechen- und Model-Logik gehört in die PHP-Suite
|
||
(`tests/NN_*.php`) – schneller und isoliert.
|
||
|
||
## Aufräumen
|
||
|
||
Jeder Lauf legt Konten, Kategorien, Klassen und Buchungen neu an – mit einer
|
||
Zeitmarke im Namen, damit zwei Läufe sich nicht ins Gehege kommen. Damit sich
|
||
das nicht ansammelt, räumt `run.sh` **vor** jedem Lauf auf:
|
||
|
||
```bash
|
||
docker compose exec -u www-data php php scripts/e2e-aufraeumen.php
|
||
docker compose exec -u www-data php php scripts/e2e-aufraeumen.php --probe # nur zählen
|
||
```
|
||
|
||
Vor dem Lauf und nicht danach, weil ein abgebrochener Lauf sonst einen Bestand
|
||
hinterlässt, an den niemand mehr denkt – und weil die Daten des letzten Laufs
|
||
so bis zum nächsten für die Fehlersuche stehen bleiben.
|
||
|
||
Gelöscht wird alles, was am Testnutzer hängt, nicht, was nach Testdaten
|
||
aussieht: Ein Namensmuster übersähe die Buchung „Supermarkt“ und träfe
|
||
irgendwann etwas Echtes. Der Nutzer selbst bleibt stehen, und er muss den
|
||
Anzeigenamen tragen, den `scripts/e2e-benutzer.php` setzt – sonst bricht das
|
||
Skript ab, statt einem echten Zugang den Bestand zu leeren.
|
||
|
||
`E2E_KEIN_AUFRAEUMEN=1` lässt den Bestand stehen:
|
||
|
||
```bash
|
||
E2E_KEIN_AUFRAEUMEN=1 tests/e2e/run.sh
|
||
```
|
||
|
||
## Grundbestand
|
||
|
||
Nach dem Aufräumen legt `run.sh` einen festgelegten Grundbestand an:
|
||
|
||
```bash
|
||
docker compose exec -u www-data php php scripts/e2e-grundbestand.php
|
||
```
|
||
|
||
Ein Teil der Tests prüft die Darstellung, nicht das Rechnen – dass ein Bericht
|
||
eine Tabelle statt eines Platzhalters zeigt, dass Zahlenspalten rechtsbündig
|
||
stehen, dass „Übrige Konten“ eine Ebene tiefer führt. Solche Tests brauchen
|
||
einen Bestand, legen ihn aber nicht selbst an; bis zum Aufräumen lebten sie von
|
||
den Resten früherer Läufe und fanden je nach Vorgeschichte etwas anderes vor.
|
||
|
||
Die Zuschnitte in `E2EGrundbestand` sind deshalb nicht beliebig: mehr Konten als
|
||
`Vermoegensentwicklung::SERIEN` (sonst fehlt „Übrige Konten“), Buchungen in jedem
|
||
Monat des laufenden Jahres (sonst bleiben Monatsspalten leer), ein Vorjahr für
|
||
den Vergleichsbericht, ein Depot mit Wertpapiergeschäft für die Wertpapierlisten.
|
||
Wer daran etwas ändert, sieht in `tests/41_E2EAufraeumenTest.php` nach: Dort steht
|
||
zu jeder Grenze, welcher Test daran hängt.
|
||
|
||
Wer eine Spec schreibt, die eigene Daten braucht, legt sie weiterhin selbst an –
|
||
der Grundbestand trägt nur die Tests, die irgendeinen Bestand voraussetzen.
|
||
|
||
## Gemeinsame Helfer
|
||
|
||
`specs/hilfen.js` liegt neben den Specs, endet aber nicht auf `.spec.js` und wird
|
||
deshalb nicht als Testdatei eingesammelt. Dort steht `komboboxWaehlen()`: Die
|
||
Typeahead-Felder aus `public/static/kombobox.js` lassen ihr `<select>` versteckt
|
||
im Formular stehen, `selectOption()` läuft darauf in einen Timeout. Der Helfer
|
||
tippt stattdessen die Beschriftung ein und klickt den genau passenden Treffer an.
|
||
|
||
```js
|
||
const { komboboxWaehlen } = require('./hilfen')
|
||
|
||
await komboboxWaehlen(zeile.locator('#zuordnungsauswahl select'), 'Lebensmittel')
|
||
```
|
||
|
||
## Berichte
|
||
|
||
HTML-Report, Screenshots und Traces landen nach einem Lauf in
|
||
`playwright-report/` und `test-results/` (beide nicht im Repository).
|