---
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`.