Mark A-1 as complete: Add detailed QA Test-Strategie for Compose Desktop App, including test pyramid, tooling, conventions, and CI/CD integration; link roadmap and strategy documents.
This commit is contained in:
parent
4ae701d969
commit
2715b75535
|
|
@ -7,11 +7,12 @@
|
|||
|
||||
## 🔴 Sprint A — Sofort (diese Woche)
|
||||
|
||||
- [ ] **A-1** | Test-Strategie für Desktop-App definieren
|
||||
- [ ] Testpyramide für Compose Desktop festlegen (Unit / Integration / UI-Tests)
|
||||
- [ ] Tooling entscheiden: `kotlin.test`, Compose UI Test, Mockk
|
||||
- [ ] Test-Konventionen dokumentieren (Namensschema, Ordnerstruktur, Arrange-Act-Assert)
|
||||
- [ ] Dokument in `docs/06_Frontend/` oder `docs/07_Infrastructure/` ablegen
|
||||
- [x] **A-1** | Test-Strategie für Desktop-App definieren — siehe „QA Test-Strategie — Compose Desktop App“
|
||||
- [x] Testpyramide für Compose Desktop festlegen (Unit / Integration / UI-Tests)
|
||||
- [x] Tooling entscheiden: `kotlin.test`, Compose UI Test, Mockk
|
||||
- [x] Test-Konventionen dokumentieren (Namensschema, Ordnerstruktur, Arrange-Act-Assert)
|
||||
- [x] Dokument in `docs/06_Frontend/` oder `docs/07_Infrastructure/` ablegen
|
||||
- 📄 Dokument: [`docs/06_Frontend/Teststrategie_Desktop.md`](../../06_Frontend/Teststrategie_Desktop.md)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
184
docs/06_Frontend/Teststrategie_Desktop.md
Normal file
184
docs/06_Frontend/Teststrategie_Desktop.md
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
# 🧐 QA Test-Strategie — Compose Desktop App
|
||||
|
||||
> Stand: 2. April 2026
|
||||
> Gültig für: Kotlin Multiplatform / Compose Desktop (JVM) Frontend
|
||||
|
||||
---
|
||||
|
||||
## Ziel
|
||||
Konsistente, schnelle und verlässliche Tests für die Desktop-App. Diese Richtlinie definiert die Testpyramide, das Tooling und verbindliche Konventionen (Benennung, Ordnerstruktur, Arrange–Act–Assert), damit Frontend, QA und DevOps nahtlos zusammenarbeiten können.
|
||||
|
||||
---
|
||||
|
||||
## Testpyramide für Compose Desktop
|
||||
|
||||
1) Unit-Tests (70–80%)
|
||||
- Reine Kotlin-Logik ohne UI: ViewModels, Reducer/Intent-Handler, Mapper/Formatter, Validatoren
|
||||
- Keine echten I/O‑Operationen, keine echten Uhren/Dispatcher → alles gemockt oder gefaked
|
||||
- Laufzeit: < 100 ms pro Test, parallelisierbar
|
||||
|
||||
2) Integrations-Tests (15–25%)
|
||||
- Zusammenspiel mehrerer Komponenten auf JVM (z. B. ViewModel + Repository mit In‑Memory/Fake Datenquelle)
|
||||
- Optionale Nutzung eines Test-Dispatchers; kein echtes Netzwerk/Dateisystem
|
||||
- Ziel: Korrekte State-Transitions, Fehlerpfade, Laden/Speichern‑Flows
|
||||
|
||||
3) UI-Tests (5–10%)
|
||||
- Compose UI Test Framework (Desktop): Semantics-basierte Interaktion und Assertions
|
||||
- Abdecken kritischer User-Flows (Happy Path + 1–2 Edge Cases)
|
||||
- Headless-fähig für CI (Xvfb/JetBrains Runtime Headless). Kürzere, robuste Tests (keine Pixel-Assertions)
|
||||
|
||||
Leitprinzip: So viel wie möglich unterhalb der UI testen (schnell/stabil), nur kritische End-to-End‑Flows als UI-Test absichern.
|
||||
|
||||
---
|
||||
|
||||
## Tooling-Entscheidung
|
||||
|
||||
- Test-Framework: `kotlin.test`
|
||||
- Einheitlich über KMP, minimaler Overhead, gute IDE/CI-Integration
|
||||
|
||||
- Mocking/Stubs: `MockK`
|
||||
- Kotlin‑freundlich, unterstützt Klassen/Objekte, klare Verifikation von Interaktionen
|
||||
|
||||
- Coroutines/Flows testen: `kotlinx-coroutines-test`
|
||||
- `StandardTestDispatcher`, `runTest {}`, virtuelle Zeitsteuerung, deterministische Tests
|
||||
|
||||
- UI-Tests: Compose UI Test (Desktop)
|
||||
- `compose.ui.test` APIs: `onNodeWithText`, `performClick`, `assertIsDisplayed`, etc.
|
||||
- Headless in CI via JVM Args/Virtual Display (DevOps setzt Runner bereit)
|
||||
|
||||
- Optional (nur falls notwendig):
|
||||
- Snapshot-Testing vermeiden (fragil im Desktop-Kontext)
|
||||
- Property-based Testing optional (z. B. mit Kotest property) — nicht Standard
|
||||
|
||||
---
|
||||
|
||||
## Ordner- und Modulstruktur (KMP/Compose Desktop)
|
||||
|
||||
Beispielhaft; bitte auf bestehende Modulnamen im Repo mappen:
|
||||
|
||||
- `frontend/` (Wurzel des KMP-Frontends)
|
||||
- `commonMain/` — UI-agnostische Logik, Models, Use-Cases, Validatoren
|
||||
- `commonTest/` — Unit- und Integrations-Tests für Common
|
||||
- `desktopMain/` — Desktop-spezifische UI (Compose Desktop) und Integrationscode
|
||||
- `desktopTest/` — UI-Tests (Compose UI Test) und Desktop-Integrations-Tests
|
||||
|
||||
Konvention:
|
||||
- Business-/State-Logik so weit wie möglich in `commonMain` halten → maximaler Anteil schneller Unit-Tests in `commonTest`.
|
||||
- UI-spezifische Tests in `desktopTest` nur für kritische End-to-End‑Flows.
|
||||
|
||||
---
|
||||
|
||||
## Benennungs- und Strukturkonventionen
|
||||
|
||||
- Test-Klassenname: `<ProduktionsKlasse>Test.kt` oder `<Feature/UseCase>Test.kt`
|
||||
- Test-Funktionsname (kotlin.test): ``fun `<Methode/Intent>_<Bedingung>_<ErwartetesVerhalten>()``
|
||||
- Beispiel: ``fun `onSave_withInvalidInput_emitsValidationError`()``
|
||||
|
||||
- Arrange–Act–Assert (AAA) strikt einhalten:
|
||||
- Arrange: Testdaten, Mocks, System Under Test (SUT) erstellen
|
||||
- Act: eine gezielte Aktion / Intent ausführen
|
||||
- Assert: erwarteten Zustand/Ereignisse prüfen
|
||||
|
||||
- Given/When/Then als Kommentare optional:
|
||||
- `// Given`, `// When`, `// Then` — keine unnötigen Kommentare, nur zur Struktur
|
||||
|
||||
- Ordner nach Domäne/Feature gruppieren (bevorzugt):
|
||||
- `commonTest/<feature>/...`, `desktopTest/<flow>/...`
|
||||
|
||||
---
|
||||
|
||||
## Coroutines & State-Tests (Beispiel)
|
||||
|
||||
```kotlin
|
||||
import kotlin.test.*
|
||||
import kotlinx.coroutines.test.*
|
||||
|
||||
class AnmeldungViewModelTest {
|
||||
@Test
|
||||
fun `onWeiter_withEmptyPflichtfeld_emitsValidationError`() = runTest {
|
||||
// Arrange
|
||||
val vm = AnmeldungViewModel(/* fakes */)
|
||||
|
||||
// Act
|
||||
vm.onWeiter()
|
||||
|
||||
// Assert
|
||||
assertTrue(vm.state.value.validationErrorShown)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Compose UI Test (Desktop) — Grundsätze
|
||||
|
||||
- Selektoren über Semantics (Text, ContentDescription, TestTags via `Modifier.testTag("…")`)
|
||||
- Keine Fragilität: Keine Pixel-/Layout‑abhängigen Asserts
|
||||
- Jeder UI-Test prüft genau einen kritischen Flow, Laufzeitziel < 3s pro Test
|
||||
|
||||
Minimalbeispiel:
|
||||
|
||||
```kotlin
|
||||
import androidx.compose.ui.test.*
|
||||
import kotlin.test.Test
|
||||
|
||||
class NennungUiTest {
|
||||
@Test
|
||||
fun startliste_filterByBewerb_showsOnlyMatchingEntries() {
|
||||
// Given
|
||||
val rule = createComposeRule()
|
||||
rule.setContent { AppRoot() }
|
||||
|
||||
// When
|
||||
rule.onNodeWithTag("filter-bewerb").performClick()
|
||||
rule.onNodeWithText("CSN-C-NEU 95cm").performClick()
|
||||
|
||||
// Then
|
||||
rule.onAllNodesWithTag("startlisten-zeile")
|
||||
.assertCountEquals( /* erwartete Anzahl */ 5)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Hinweis: Die konkrete Setup-/Runner-Konfiguration für Headless-Ausführung wird in `docs/07_Infrastructure/ci-testing.md` (DevOps) dokumentiert.
|
||||
|
||||
---
|
||||
|
||||
## Testdaten und Fakes
|
||||
|
||||
- Fakes statt Mocks, wenn Verhalten wichtiger als Interaktion ist (z. B. InMemoryRepository)
|
||||
- Test-Datenbuilder verwenden (kleine DSLs / Fabriken) statt anonymer Maps/Listen
|
||||
- Zeitabhängiges Verhalten: `TestCoroutineScheduler` + injizierbare Clock/Now‑Provider
|
||||
|
||||
---
|
||||
|
||||
## Qualitätsregeln für Tests
|
||||
|
||||
- Stabilität > Vollständigkeit: flaky Tests sind zu entfernen oder neu zu schneiden
|
||||
- Ein Test – ein Verhalten: keine überladenen Tests
|
||||
- Determinismus: keine versteckten Sleeps/Delays, virtuelle Zeit nutzen
|
||||
- Lesbarkeit: AAA, sprechende Namen, knappe Arrange‑Blöcke
|
||||
|
||||
---
|
||||
|
||||
## CI/CD‑Integration (Kurz)
|
||||
|
||||
- Unit/Integrations: JVM headless, parallel (Gradle `--parallel`), `-Dkotlinx.coroutines.scheduler.keep.alive.sec=…` falls nötig
|
||||
- UI: Headless via Xvfb oder JBR Headless; kurzer Smoke‑Satz ausführen
|
||||
- Reports: Gradle HTML/JUnit XML; Flaky-Tracking über CI möglich
|
||||
|
||||
---
|
||||
|
||||
## Checkliste (DoD)
|
||||
|
||||
- [ ] Neuer Test folgt AAA und Namenskonvention
|
||||
- [ ] Läuft headless lokal und in CI
|
||||
- [ ] Keine externen Abhängigkeiten ohne Fake/Mock
|
||||
- [ ] UI-Test nutzt Semantics/TestTags und ist robust
|
||||
|
||||
---
|
||||
|
||||
## Verweise
|
||||
|
||||
- Roadmap: `docs/04_Agents/Roadmaps/QA_Roadmap.md` (Punkt A-1)
|
||||
- DevOps (Headless/CI): `docs/07_Infrastructure/` (geplantes Dokument `ci-testing.md`)
|
||||
Loading…
Reference in New Issue
Block a user