--- model: sonnet --- # AP10 – Architekturtest > **Meilenstein:** M1 > **Vorgänger:** AP04, AP09 ✅ erforderlich (alle AP05–AP09 sollten abgeschlossen sein) > **Nachfolger:** AP11 > **Grundlage:** `docs/specs/technik-und-architektur.md` v5, §§ „Architekturprinzipien", „Test- und Qualitätsanforderungen" > **Entscheidungsprotokoll:** `docs/arbeitspakete/m1/E00-entscheidungsprotokoll.md` (E-02 Test-Log, E-03 leere Testklasse) ## Ziel Automatisierte Architekturtests sichern die in M1 etablierten Strukturregeln dauerhaft ab. Zusätzlich wird das Build-Rauschen durch ERROR-Log-Zeilen in Negativ-Tests beseitigt. ## Voraussetzungen - AP04 (Logging-Adapter etabliert) - AP09 (Preview-Code eingefroren) - Idealerweise alle AP05–AP09 abgeschlossen ## Scope IN ### 1. ArchUnit als Test-Dependency ```xml com.tngtech.archunit archunit-junit5 test ``` ### 2. Architekturtest-Klasse Neue Testklasse `de.gecheckt.asv.ArchitectureTest` im Testbereich. Mindestens vier Regeln: **Regel A — Log4j2-Sichtbarkeit:** ```java @ArchTest static final ArchRule log4j2_nur_in_logging_adapter_und_bootstrap = noClasses() .that().resideOutsideOfPackages( "de.gecheckt.asv.adapter.out.logging..", "de.gecheckt.asv.bootstrap..") .should().dependOnClassesThat() .resideInAPackage("org.apache.logging.log4j..") .because("Log4j2 darf nur im Logging-Adapter und im Bootstrap sichtbar sein."); ``` **Regel B — Domain-Reinheit:** ```java @ArchTest static final ArchRule domain_hat_keine_adapter_abhaengigkeit = noClasses() .that().resideInAPackage("de.gecheckt.asv.domain..") .should().dependOnClassesThat() .resideInAnyPackage( "de.gecheckt.asv.adapter..", "de.gecheckt.asv.bootstrap.."); ``` **Regel C — Application-Reinheit:** ```java @ArchTest static final ArchRule application_kennt_keine_adapter_implementierungen = noClasses() .that().resideInAPackage("de.gecheckt.asv.application..") .should().dependOnClassesThat() .resideInAnyPackage( "de.gecheckt.asv.adapter..", "de.gecheckt.asv.bootstrap.."); ``` **Regel D — Preview-Isolation:** ```java @ArchTest static final ArchRule preview_wird_nicht_aus_aktivem_code_referenziert = noClasses() .that().resideInAnyPackage( "de.gecheckt.asv.adapter..", "de.gecheckt.asv.bootstrap..") .should().dependOnClassesThat() .haveSimpleNameContaining("DefaultStructureValidator") .orShould().dependOnClassesThat() .haveSimpleNameContaining("DefaultFieldValidator") .because("Preview-Validatoren sind in M1 eingefroren und werden erst ab M3 aktiv verwendet."); ``` **Wichtig:** Wenn beim ersten Lauf Regeln rot sind, **müssen die Verstöße behoben werden** — die Regeln werden nicht abgeschwächt. ### 3. Test-Log-Konfiguration (E-02) `src/test/resources/log4j2-test.xml` anlegen: ```xml ``` Log4j2 bevorzugt `log4j2-test.xml` im Test-Classpath gegenüber `log4j2.xml`. Das unterdrückt die erwartete ERROR-Zeile aus dem CLI-Negativ-Test. ### 4. Aufräumen - Prüfen ob `DefaultStructureValidatorTestAdditional` bereits in AP09 gelöscht wurde — falls nicht, hier löschen - Sicherstellen dass keine weiteren leeren Testklassen im Projekt existieren ## Scope OUT - Komplexe Regeln wie zyklische Abhängigkeiten — für M1 zu weitgehend - Regeln zu Klassenbenennung oder `public`-Sichtbarkeit - Coverage- und Mutation-Schwellwerte (kommen erst in M9) - Neue Produktionsklassen ## Schritte 1. ArchUnit in `pom.xml` als Test-Dependency aufnehmen 2. `ArchitectureTest`-Klasse mit den vier Regeln implementieren 3. `log4j2-test.xml` unter `src/test/resources/` anlegen 4. `mvn clean verify` ausführen — alle vier ArchUnit-Regeln müssen grün sein 5. Falls Regeln rot: Verstöße identifizieren, beheben, erneut testen 6. Im Bericht dokumentieren ob beim ersten Lauf Regeln rot waren und wie behoben 7. Abschlussbericht schreiben ## Abnahmekriterien - [ ] ArchUnit als Test-Dependency in `pom.xml` - [ ] Vier Architekturregeln A–D implementiert und grün - [ ] `log4j2-test.xml` unter `src/test/resources/` vorhanden - [ ] Keine leeren Testklassen im Projekt - [ ] `mvn clean verify` grün, kein unerwartetes Log-Rauschen - [ ] Bericht dokumentiert ob erste Ausführung Regeln rot hatte und wie behoben - [ ] Abschlussbericht unter `docs/arbeitspakete/m1/berichte/AP10-bericht.md` ## Rest-Risiken und offene Punkte - ArchUnit hat beim ersten Einsatz manchmal Überraschungen mit transitiven Abhängigkeiten (Regel greift auch auf Framework-Klassen). In dem Fall: Regel präzisieren, **nicht** ausschalten. - Regel D (Preview-Isolation) ist auf Klassennamen-Basis formuliert, weil kein separates Paket existiert (Option b). Falls das zu fragil ist, kann alternativ auf Package-Ebene mit einem `preview`-Paket geprüft werden — aber nur wenn AP09 entsprechend umgebaut wurde. ## Bericht `docs/arbeitspakete/m1/berichte/AP10-bericht.md` nach `docs/arbeitspakete/m1/templates/ap-bericht.md`.