Umsetzung von M1
This commit is contained in:
@@ -1,26 +1,42 @@
|
||||
---
|
||||
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
|
||||
|
||||
Ein **automatisierter Architekturtest** stellt sicher, dass die in M1 etablierten Strukturregeln auch in Zukunft eingehalten werden. Insbesondere darf:
|
||||
|
||||
1. die **Log4j2-Bindung** nur in `adapter.out.logging` und `bootstrap` sichtbar sein
|
||||
2. das `domain`-Paket **nichts** aus Adaptern oder Infrastruktur importieren
|
||||
3. das `application`-Paket **nichts** aus konkreten Adaptern importieren, sondern nur aus `domain` und eigenen Ports
|
||||
4. **Preview-Code** nicht aus dem aktiven Code (Bootstrap, CLI-Adapter, Application) referenziert werden
|
||||
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), AP09 (Preview eingefroren)
|
||||
- AP04 (Logging-Adapter etabliert)
|
||||
- AP09 (Preview-Code eingefroren)
|
||||
- Idealerweise alle AP05–AP09 abgeschlossen
|
||||
|
||||
## Scope IN
|
||||
|
||||
### Technische Umsetzung
|
||||
- **ArchUnit** (`com.tngtech.archunit:archunit-junit5`) als Test-Dependency aufnehmen
|
||||
- neue Test-Klasse `ArchitectureTest` im Paket `de.gecheckt.asv` im Testbereich
|
||||
- vier Tests:
|
||||
### 1. ArchUnit als Test-Dependency
|
||||
|
||||
### Test 1: Log4j2-Sichtbarkeit
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.tngtech.archunit</groupId>
|
||||
<artifactId>archunit-junit5</artifactId>
|
||||
<version><!-- aktuell stabile Version --></version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 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 =
|
||||
@@ -33,7 +49,7 @@ static final ArchRule log4j2_nur_in_logging_adapter_und_bootstrap =
|
||||
.because("Log4j2 darf nur im Logging-Adapter und im Bootstrap sichtbar sein.");
|
||||
```
|
||||
|
||||
### Test 2: Domain ist frei
|
||||
**Regel B — Domain-Reinheit:**
|
||||
```java
|
||||
@ArchTest
|
||||
static final ArchRule domain_hat_keine_adapter_abhaengigkeit =
|
||||
@@ -42,11 +58,10 @@ static final ArchRule domain_hat_keine_adapter_abhaengigkeit =
|
||||
.should().dependOnClassesThat()
|
||||
.resideInAnyPackage(
|
||||
"de.gecheckt.asv.adapter..",
|
||||
"de.gecheckt.asv.bootstrap..",
|
||||
"de.gecheckt.asv.preview..");
|
||||
"de.gecheckt.asv.bootstrap..");
|
||||
```
|
||||
|
||||
### Test 3: Application ist frei von konkreten Adaptern
|
||||
**Regel C — Application-Reinheit:**
|
||||
```java
|
||||
@ArchTest
|
||||
static final ArchRule application_kennt_keine_adapter_implementierungen =
|
||||
@@ -58,53 +73,82 @@ static final ArchRule application_kennt_keine_adapter_implementierungen =
|
||||
"de.gecheckt.asv.bootstrap..");
|
||||
```
|
||||
|
||||
### Test 4: Preview wird nicht referenziert
|
||||
**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.application..",
|
||||
"de.gecheckt.asv.bootstrap..",
|
||||
"de.gecheckt.asv.domain..")
|
||||
"de.gecheckt.asv.bootstrap..")
|
||||
.should().dependOnClassesThat()
|
||||
.resideInAPackage("de.gecheckt.asv.preview..")
|
||||
.because("Preview-Code ist aus M1-Sicht eingefroren und wird erst ab M3 aktiv verwendet.");
|
||||
.haveSimpleNameContaining("DefaultStructureValidator")
|
||||
.orShould().dependOnClassesThat()
|
||||
.haveSimpleNameContaining("DefaultFieldValidator")
|
||||
.because("Preview-Validatoren sind in M1 eingefroren und werden erst ab M3 aktiv verwendet.");
|
||||
```
|
||||
|
||||
### Zusätzlich: Paketstruktur-Check
|
||||
- Prüfen, dass die Soll-Pakete aus `technik-und-architektur.md` tatsächlich existieren (als ArchUnit-Regel oder einfacher Dateisystem-Test)
|
||||
**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
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_ERR">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="WARN">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
- komplexere Regeln wie „keine zyklischen Abhängigkeiten zwischen Paketen" — wäre schön, ist aber für M1 zu weitgehend
|
||||
- Regeln zu Klassenbenennung
|
||||
- Regeln zu `public`-Sichtbarkeit
|
||||
- Tests für Preview-internen Aufbau
|
||||
- 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. Branch `m1/ap10-architekturtest`
|
||||
2. ArchUnit in `pom.xml` als Test-Dependency aufnehmen
|
||||
3. `ArchitectureTest`-Klasse im Testbereich anlegen
|
||||
4. Die vier Regeln implementieren
|
||||
5. `mvn clean verify` laufen lassen — die Tests müssen **grün** sein. Falls rot: **das heißt, eine frühere M1-Phase hat die Regel verletzt**. Die Verletzung muss gefunden und behoben werden (kein Entschärfen der Regel!).
|
||||
6. Commit `M1-AP10: Architekturtest für Log4j2-Sichtbarkeit, Paketabhängigkeiten, Preview-Isolation`
|
||||
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 ist als Test-Dependency eingebunden
|
||||
- vier Architektur-Regeln sind implementiert und grün
|
||||
- `mvn clean verify` ist grün
|
||||
- Abschlussbericht liegt vor und dokumentiert, ob beim ersten Lauf Regeln rot waren und wenn ja, wie sie behoben wurden
|
||||
- [ ] 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, die nicht gemeint waren). In dem Fall: Regel präzisieren, **nicht** ausschalten.
|
||||
- Die Regel „Log4j2-Sichtbarkeit" schließt auch den Bootstrap mit ein. Wenn der Bootstrap später (M8) Krypto-Typen referenziert, müssen analoge Regeln ergänzt werden — aber das ist M8-Thema.
|
||||
- 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 `templates/ap-bericht.md`.
|
||||
`docs/arbeitspakete/m1/berichte/AP10-bericht.md` nach `docs/arbeitspakete/m1/templates/ap-bericht.md`.
|
||||
|
||||
Reference in New Issue
Block a user