# NEXARCH Core – Teststrategie Stand: 2026-08-28. Ticket: QA-01. ## 1. Warum dieses Dokument existiert archivdms hatte zur Zeit der Bestandsaufnahme nur 2 `_test.go`-Dateien in ganz `internal/`, davon 0 für `auth`/`storage`/`permissions.go`. archivmail testete 2 von 18 Modulen. Beide Lücken wurden erst im Betrieb entdeckt, nicht vor dem Merge. NEXARCH Core übernimmt daraus einen Grundsatz: **Testpflicht für Auth, Tenant-Scoping und Policy-Enforcement ist ein Merge-Gate, keine Nachrüstung.** ## 2. Testpyramide | Ebene | Werkzeug | Umfang | |---|---|---| | Unit | `go test` (Standardbibliothek) | Einzelne Funktionen/Typen, keine externe Abhängigkeit (DB, Netzwerk) | | Integration | `go test` gegen echte PostgreSQL-Instanz (`nexarch_test`-Rolle) | Repository-/Handler-Schicht, Tenant-Scoping, Policy-Enforcement | | Vertragstests | `internal/contracttest` (siehe QA-07) | Öffentliche API-Verträge zwischen Core und Modulen | | Last-/Leistungstests | `internal/loadtest` (siehe QA-08) | Mehrmodul-Last, JWT-Verifikation, Connection-Pooling | | Extern | Core `QA-06` Penetrationstest | Vor Produktivbetrieb, außerhalb dieses CI-Gates | Diese Kachel (QA-01) legt die Pflichtebenen fest und erzwingt sie technisch für die drei sicherheitskritischsten Bereiche; sie ersetzt nicht QA-07/QA-08, die eigene, bereits umgesetzte CI-Gates haben. ## 3. Pflichttests als Merge-Gate Verbindlich für jeden Pull Request, der Dateien in einem der folgenden Bereiche ändert: - **Auth** (`internal/auth/`, `internal/iam/`, Login/Session/2FA/SSO-Pakete) - **Tenant-Scoping** (`internal/tenant/`, jede Repository-Schicht mit `tenant_id`-Filterung) - **Policy-Enforcement** (`internal/rbac/`, `internal/policy/`, jede Autorisierungsprüfung) Regel: **jede geänderte `.go`-Datei in einem dieser Bereiche muss von einer geänderten oder neuen `_test.go`-Datei im selben Package begleitet sein.** Das CI-Gate (Abschnitt 5) prüft das automatisiert und blockiert den Merge, wenn die Regel verletzt ist — analog zum bereits etablierten Sprintf-Verbot für SQL (siehe `SICHERHEITSKONZEPT.md`), nur als technisch erzwungene statt nur dokumentierte Regel. Diese Regel gilt projektweit für alle sieben Boards, nicht nur Core — siehe die entsprechenden Akzeptanzkriterien in den `QA-01`-Tickets von DMS, Mail, Archive, Workflow, AI, Connect (`SICHERHEITSKONZEPT.md` Abschnitt 11, Punkt 8, 2026-08-28 geklärt). ## 4. Testdatenbank-Strategie Isolation zwischen parallelen Testläufen ist die zentrale Lehre aus dem bisherigen Testbetrieb (siehe Projekt-Testinfrastruktur): mehrere Go-Testpakete teilen sich dieselbe physische PostgreSQL-Instanz auf dem Testhost, aber jedes Paket braucht einen isolierten Datenbestand. - **Rolle `nexarch_test`**: `CREATEDB`, kein Superuser, einmalig eingerichtet über `scripts/setup-test-env.sh`. - **Reset vor jedem Testlauf**: `scripts/reset-test-env.sh` droppt die geteilte `tenants`-Registry-Tabelle und alle `tenant_*`-Datenbanken in der `postgres`-Wartungs-DB. Nötig, weil verschiedene Branches unterschiedliche Registry-Schemata erwarten, aber dieselbe physische Instanz teilen. - **`-p 1` ist Pflicht** für `go test ./...`, sobald mehrere Pakete gegen die geteilte Registry-Tabelle testen (z. B. `internal/tenant` + `internal/migrate`). Ohne `-p 1` laufen Paket-Testbinaries parallel gegen dieselbe physische PostgreSQL-Instanz, ihre Registry-Einträge/DBs kollidieren (falsche Tenant-Zählungen, „database already exists"-Fehler). - **Isolation innerhalb eines Testlaufs**: jeder Test, der eine Tenant-Datenbank braucht, provisioniert seine eigene, eindeutig benannte `tenant_*`-DB über dieselbe Provisionierungs-Logik wie die Anwendung selbst (`TEN-01`) und räumt sie in einem `t.Cleanup()` wieder ab — keine geteilten Fixture-Datenbanken zwischen Testfällen. Siehe `internal/testdbisolation/isolation_test.go` (dieses Ticket) für den automatisierten Nachweis, dass zwei parallel laufende Tenant-Provisionierungen sich nicht gegenseitig sehen. ## 5. CI-Gate `.gitea/workflows/pflichttest-gate.yml` führt `cmd/pflichttestgate` gegen den PR-Diff aus (`git diff --name-only origin/...HEAD`). Das Programm: 1. Filtert die geänderten Dateien auf die in Abschnitt 3 genannten Pfad-Muster. 2. Prüft je betroffenem Go-Package, ob mindestens eine `_test.go`-Datei desselben Packages ebenfalls im Diff enthalten ist. 3. Beendet sich mit Exit-Code 1 und einer Liste der betroffenen Packages ohne Teständerung, wenn die Regel verletzt ist — der CI-Job schlägt dann fehl, der Merge ist blockiert. Negativtest des Gates selbst: `internal/pflichttestgate/gate_test.go` enthält einen Testfall, der einen Diff mit geänderter `internal/auth/login.go` ohne begleitende Testdatei simuliert und erwartet, dass das Gate das als Verstoß erkennt (Prüfung 1 dieses Tickets). ## 6. Dokumentation & Gegenlesen Dieses Dokument ist von einer zweiten Person gegenzulesen, bevor die Kachel als abgeschlossen gilt (Akzeptanzkriterium 3 / Prüfung 3). Fund/Freigabe wird im Pull Request vermerkt.