Updated Modultestplan

main
Lucas Strubel 2026-06-15 16:04:17 +02:00
parent 4789cbabf1
commit 77e3ec2a33
3 changed files with 211 additions and 77 deletions

View File

@ -1,9 +1,9 @@
--- ---
title: "Modultestplan" title: "Modultestplan"
subtitle: "Desktop-Fakturierungsanwendung — Gruppe A: Prozess / Dokumentenzyklus" subtitle: "Desktop-Fakturierungsanwendung — Gesamtsystem (alle Komponenten)"
author: author:
- Team 1 Gruppe A - Team 1
version: "1.0" version: "2.0"
lang: de-DE lang: de-DE
toc: true toc: true
toc-depth: 3 toc-depth: 3
@ -20,12 +20,19 @@ header-includes: |
\usepackage{lastpage} \usepackage{lastpage}
\pagestyle{fancy} \pagestyle{fancy}
\fancyhf{} \fancyhf{}
\fancyhead[L]{Team 1 Gruppe A} \fancyhead[L]{Team 1}
\fancyhead[C]{Modultestplan} \fancyhead[C]{Modultestplan}
\fancyhead[R]{Version 1.0} \fancyhead[R]{Version 2.0}
\fancyfoot[C]{\thepage\ /\ \pageref{LastPage}} \fancyfoot[C]{\thepage\ /\ \pageref{LastPage}}
\renewcommand{\headrulewidth}{0.4pt} \renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0pt} \renewcommand{\footrulewidth}{0pt}
\makeatletter
\def\brk@scan#1{\ifx\brk@end#1\else#1\allowbreak\expandafter\brk@scan\fi}
\newcommand{\brk}[1]{\brk@scan#1\brk@end}
\let\origtexttt\texttt
\renewcommand{\texttt}[1]{\origtexttt{\brk{#1}}}
\makeatother
\AtBeginEnvironment{longtable}{\small}
--- ---
\newpage \newpage
@ -35,103 +42,230 @@ header-includes: |
+=========================+=========================+=========================+ +=========================+=========================+=========================+
| Strubel, Lucas | Prof. Dr. Marmitt, Gerd | Prof. Dr. Marmitt, Gerd | | Strubel, Lucas | Prof. Dr. Marmitt, Gerd | Prof. Dr. Marmitt, Gerd |
+-------------------------+-------------------------+-------------------------+ +-------------------------+-------------------------+-------------------------+
| Gruppe A (Prozess) | Modulverantwortlicher | Modulverantwortlicher | | Team 1 (Gesamtsystem) | Modulverantwortlicher | Modulverantwortlicher |
+-------------------------+-------------------------+-------------------------+ +-------------------------+-------------------------+-------------------------+
| 15.06.2026 | 15.06.2026 | 15.06.2026 | | 15.06.2026 | 15.06.2026 | 15.06.2026 |
+-------------------------+-------------------------+-------------------------+ +-------------------------+-------------------------+-------------------------+
**Freigabevermerk:** Dieses Dokument ist nach Prüfung und Freigabe durch den **Freigabevermerk:** Dieses Dokument ist nach Prüfung und Freigabe durch den
Modulverantwortlichen verbindliche Grundlage für den Modultest der Komponente Modulverantwortlichen verbindliche Grundlage für den Modultest des Gesamtsystems
*Prozess / Dokumentenzyklus*. *Desktop-Fakturierungsanwendung* (Komponenten AD, gemeinsame Infrastruktur sowie
Performance-Nachweise).
## Dokumentenhistorie ## Dokumentenhistorie
| Version | Datum | Autor | Grund der Änderung | | Version | Datum | Autor | Grund der Änderung |
|---------|------------|-----------------------------|---------------------| |---------|------------|-----------------------------|---------------------|
| 1.0 | 15.06.2026 | Lucas Strubel | Initiale Erstellung (ausgegliedert aus Pflichtenheft Gruppe A v1.2) | | 1.0 | 15.06.2026 | Lucas Strubel | Initiale Erstellung (ausgegliedert aus Pflichtenheft Gruppe A v1.2) |
| 2.0 | 15.06.2026 | Lucas Strubel | Konsolidierung aller Komponenten-Testfälle (AD, gemeinsame Infrastruktur, Performance) in einen projektweiten Modultestplan |
\newpage \newpage
## 1. Einleitung ## 1. Einleitung
### 1.1 Zweck des Dokuments ### 1.1 Zweck des Dokuments
Dieser Modultestplan spezifiziert die Modul-/Komponententests der Komponente Dieser Modultestplan spezifiziert die Modul-/Komponententests des **Gesamtsystems**
*Prozess / Dokumentenzyklus* (Gruppe A). Er leitet sich direkt aus dem Pflichtenheft *Desktop-Fakturierungsanwendung*. Er fasst die Testfälle aller vier Komponenten
Gruppe A (ab Version 1.2) ab — insbesondere aus den funktionalen Anforderungen (Kapitel 4), (A Prozess/Dokumentenzyklus, B Produktverwaltung, C Kundenverwaltung,
den Daten und Schnittstellen (Kapitel 6) sowie den testbaren Abnahmekriterien (Kapitel 8) — D Programmoberfläche), der gemeinsam genutzten Infrastruktur (Paket `gemeinsam`) sowie
und überführt diese in deterministische, mit JUnit umsetzbare Testfälle. die übergreifenden Performance-/Lastnachweise in einem Dokument zusammen. Die Testfälle
leiten sich aus den funktionalen Anforderungen, Daten/Schnittstellen und testbaren
Abnahmekriterien der jeweiligen Pflichtenhefte ab und überführen diese in deterministische,
mit JUnit 5 umgesetzte Testfälle. Quelle der Wahrheit sind die Testklassen unter
`src/test/java/de/team1/faktura/…`.
### 1.2 Rahmenbedingungen ### 1.2 Rahmenbedingungen
Die folgenden Testfälle sind deterministisch (feste Ein-/Ausgaben) und mit JUnit 5 Die folgenden Testfälle sind deterministisch (feste Ein-/Ausgaben) und mit JUnit 5
umsetzbar. Geldbeträge werden als `BigDecimal` mit Scale 2 erwartet umgesetzt. Geldbeträge werden als `java.math.BigDecimal` mit **Scale 2** erwartet
(`assertEquals(new BigDecimal("119.00"), …)` bzw. `compareTo`). Die Schnittstellen der (`assertEquals(new BigDecimal("119.00"), …)` bzw. `compareTo`). Die jeweils benachbarten
Gruppen B (Produkte) und C (Kunden) sowie der PDF-Export werden in den Tests durch Stubs Komponenten werden im Modultest durch **Stubs/Mocks** ersetzt:
ersetzt.
- **Komponente A** ersetzt die Schnittstellen der Gruppen B (Produkte) und C (Kunden) sowie
den PDF-Export durch Stubs.
- **Komponente B** ersetzt die Schnittstelle `ProduktReferenzPruefung` (Gruppe A) durch einen Stub.
- **Komponente C** ersetzt die Schnittstelle `KundenReferenzPruefung` (Gruppe A) durch einen Stub.
- **Komponente D** ersetzt die Service-Schnittstellen der Gruppen AC durch Stubs/Mocks.
Die Abkürzungen für die abgedeckten Pflichtenheft-Anforderungen (Spalte *Abgedeckte
PH-Anf.*) sind **komponentenlokal** zu lesen: `F-01` in Abschnitt 2.2 bezeichnet eine
Anforderung des Pflichtenhefts B, nicht des Pflichtenhefts A.
## 2. Testfälle ## 2. Testfälle
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+ ### 2.1 Komponente A — Prozess / Dokumentenzyklus
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
+=======+====================+=============================+===========================+=============================+
| TC-01 | F-23, F-03 | Position mit Netto 100.00 | `berechne()` | Steuer = 19.00, Brutto = |
| | | €, Steuersatz 0.19 | | 119.00 (Scale 2) |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-02 | F-23 | Einzelpreis 50.00 €, | Positionssumme | positionssummeNetto = |
| | | Menge 3 | berechnen | 150.00 |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-03 | F-03, F-13 | Beleg mit 2 Positionen | Summen berechnen | summeNetto = 200.00, |
| | | (150.00 € @ 0.19; | | summeSteuer = 32.00, |
| | | 50.00 € @ 0.07) | | summeBrutto = 232.00 |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-04 | F-12, GR-01 | Letzte Rechnungsnummer | `naechsteNummer` | liefert `R-2026-000124` |
| | | `R-2026-000123` | `(RECHNUNG, 2026)` | (lückenlos) |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-05 | F-12 (Format) | Zähler = 7, Jahr 2026 | `naechsteNummer` | liefert `R-2026-000007` |
| | | | `(RECHNUNG, 2026)` | (führende Nullen, `String`) |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-06 | F-14, GR-06 | Rechnungsdatum 2026-06-09, | Rechnung erstellen | zahlungsziel = |
| | | kein Zahlungsziel | | 2026-06-23 (+14 Tage) |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-07 | F-14 | Rechnungsdatum 2026-06-09, | Rechnung erstellen | zahlungsziel = 2026-07-31 |
| | | Zahlungsziel 2026-07-31 | | (übernommen) |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-08 | F-24, NF-INT-01 | Rechnung im Status | `setzePosition(...)` / | wirft |
| | | `VERSENDET` | Änderung | `IllegalStateException` |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-09 | F-19, F-20 | Rechnung im Status `OFFEN` | `storniere()` | Status = `STORNIERT`; |
| | | | | nicht in |
| | | | | `offeneRechnungen()`; |
| | | | | `storniertAm` gesetzt |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-10 | F-22, GR-05 | Angebot `AN-2026-000001` | `ausAngebot(angebot)` | AB übernimmt Kunde/ |
| | | mit Kunde + 2 Positionen | (AB erzeugen) | Positionen/Mengen; |
| | | | | `vorgaengerNr` = |
| | | | | `"AN-2026-000001"` |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-11 | F-23, F-24 | Rechnung mit Produkt @ | erste Rechnung erneut | einzelpreisNetto bleibt |
| | | 50.00 €; danach | lesen | 50.00 (Snapshot |
| | | Produktpreis → 80.00 € | | unverändert) |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-12 | F-18, NF-USE-02 | Rechnung ohne Kunde | `speichere()` | Speichern abgelehnt; |
| | | **oder** ohne Position | | Validierungsfehler benennt |
| | | | | fehlendes Pflichtfeld |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
| TC-13 | F-11, F-12, F-13 | Kunde + 1 Position | vollständige Rechnung | Rechnung gespeichert, |
| | | vorhanden | erstellen | Nummer vergeben, alle |
| | | | | § 14 UStG-Pflichtangaben |
| | | | | gesetzt |
+-------+--------------------+-----------------------------+---------------------------+-----------------------------+
Damit sind 13 Testfälle (> 10) spezifiziert, die alle funktionalen Kernregeln (F-12, F-14, #### 2.1.1 Dokumentenzyklus (`DokumentzyklusTest`)
F-18, F-22, F-23, F-24) sowie die zentralen Geschäftsregeln (GR-01, GR-02, GR-03, GR-05,
GR-06) abdecken.
## 3. Abkürzungen | TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-01 | F-23, F-03 | Position mit Netto 100.00 €, Steuersatz 0.19 | `berechne()` | Steuer = 19.00, Brutto = 119.00 (Scale 2) |
| TC-02 | F-23 | Einzelpreis 50.00 €, Menge 3 | Positionssumme berechnen | positionssummeNetto = 150.00 |
| TC-03 | F-03, F-13 | Beleg mit 2 Positionen (150.00 € @ 0.19; 50.00 € @ 0.07) | Summen berechnen | summeNetto = 200.00, summeSteuer = 32.00, summeBrutto = 232.00 |
| TC-04 | F-12, GR-01 | Letzte Rechnungsnummer `R-2026-000123` | `naechsteNummer(RECHNUNG, 2026)` | liefert `R-2026-000124` (lückenlos) |
| TC-05 | F-12 (Format) | Zähler = 7, Jahr 2026 | `naechsteNummer(RECHNUNG, 2026)` | liefert `R-2026-000007` (führende Nullen, `String`) |
| TC-06 | F-14, GR-06 | Rechnungsdatum 2026-06-09, kein Zahlungsziel | Rechnung erstellen | zahlungsziel = 2026-06-23 (+14 Tage) |
| TC-07 | F-14 | Rechnungsdatum 2026-06-09, Zahlungsziel 2026-07-31 | Rechnung erstellen | zahlungsziel = 2026-07-31 (übernommen) |
| TC-08 | F-24, NF-INT-01 | Rechnung im Status `VERSENDET` | `setzePositionen(...)` / Änderung | wirft `IllegalStateException` |
| TC-09 | F-19, F-20 | Rechnung im Status `OFFEN` | `storniere()` | Status = `STORNIERT`; nicht in `offeneRechnungen()`; `storniertAm` und `storniertVon` gesetzt |
| TC-10 | F-22, GR-05 | Angebot `AN-2026-000001` mit Kunde + 2 Positionen | `erzeugeFolgebeleg(angebot)` (AB erzeugen) | AB übernimmt Kunde/Positionen/Mengen; `vorgaengerNr` = `"AN-2026-000001"` |
| TC-11 | F-23, F-24 | Rechnung mit Produkt @ 50.00 €; danach Produktpreis → 80.00 € | erste Rechnung erneut lesen | einzelpreisNetto bleibt 50.00 (Snapshot unverändert) |
| TC-12 | F-18, NF-USE-02 | Rechnung ohne Kunde **oder** ohne Position | `erstelleRechnung(...)` | Speichern abgelehnt; Validierungsfehler benennt fehlendes Pflichtfeld (`Kunde` bzw. `Position`) |
| TC-13 | F-11, F-12, F-13 | Kunde + 1 Position vorhanden | vollständige Rechnung erstellen | Rechnung gespeichert, Nummer `R-2026-…` vergeben, alle § 14 UStG-Pflichtangaben gesetzt |
#### 2.1.2 Belegpersistenz (`JsonDokumentRepositoryTest`)
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-14 | IF-01 (GoBD) | Repository mit gespeicherter Rechnung `R-2026-000001` (OFFEN) und Angebot `AN-2026-000001` (ENTWURF) | Repository neu instanziieren (Neustart) | beide Belege geladen (`alle().size() == 2`); polymorphe Typen `Rechnung`/`Angebot` bleiben erhalten; Positionen ≠ `null` |
#### 2.1.3 PDF-Export (`PdfBoxPdfExporterTest`)
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-15 | F-15, IF-01 | Vollständige Rechnung `R-2026-000001` | `exportiere(rechnung, ziel)` | PDF-Datei existiert am Zielpfad |
| TC-16 | F-15 (Robustheit) | Rechnung `R-2026-000099` mit Altdaten-Position (`produktReferenz`/`einzelpreisNetto`/`positionssummeNetto` = `null`) | `exportiere(rechnung, ziel)` | kein Fehler (`assertDoesNotThrow`); PDF-Datei existiert |
| TC-17 | F-23 (Robustheit) | Rechnung `R-2026-000098` mit `null`-Positionssummen | Summen berechnen | summeNetto = summeSteuer = summeBrutto = 0.00 (Scale 2) |
#### 2.1.4 CSV-Datenexport der Belege (`DokumentCsvExportTest`)
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-18 | Q-08, IF-04 | Repository mit 2 Rechnungen (je 1 Position); eine storniert (Datum 2026-06-10, Benutzer „Anwender") | `exportiereCsv(ziel)` | CSV mit Kopfzeile `belegnummer;belegtyp;datum;status…` + je Position eine Zeile (3 Zeilen); enthält `R-2026-000001` sowie `STORNIERT`/`Anwender` |
### 2.2 Komponente B — Produktverwaltung
PH-Anf.-Nummern beziehen sich auf das Pflichtenheft Gruppe B. Die Schnittstelle
`ProduktReferenzPruefung` (Gruppe A) wird durch einen Stub ersetzt.
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-01 | F-01, F-02 | Höchste Produktnummer `P-000041` | Produkt („Beratungsstunde", 80.00, 0.19) speichern | Produkt persistiert; Produktnummer = `P-000042` |
| TC-02 | F-02 (Format) | Zähler = 7 | `naechsteNummer()` | liefert `P-000007` (führende Nullen, `String`) |
| TC-03 | F-03 | gültiges Produkt | Einzelpreis `-1.00` | Speichern abgelehnt (Validierungsfehler „Einzelpreis") |
| TC-04 | F-03 | gültiges Produkt | Steuersatz `0.15` | Speichern abgelehnt (unzulässiger Steuersatz) |
| TC-05 | F-04, NF-USE-01 | Produkt ohne Bezeichnung | `speichere()` | Speichern abgelehnt; Validierungsfehler benennt „Bezeichnung" |
| TC-06 | F-05 | Produkt `P-000042` mit Preis 80.00 | Preis auf 95.00 ändern, speichern | gespeichertes Produkt hat einzelpreisNetto = 95.00 |
| TC-07 | F-07 | Produkt `P-000042` | Änderungsversuch der Produktnummer auf `P-999999` | wirft `IllegalArgumentException` / Änderung abgelehnt |
| TC-08 | F-08 | Produkt unverknüpft (Stub: `istProduktReferenziert``false`) | `loescheProdukt("P-000011")` mit Bestätigung | Produkt entfernt; nicht mehr in `alleSortiertNachBezeichnung()` |
| TC-09 | F-09, F-10 | Stub: `istProduktReferenziert("P-000010")``true` | `loescheProdukt("P-000010")` | Löschen abgelehnt; Produkt weiterhin vorhanden; Hinweis erzeugt |
| TC-10 | F-11 | Produkte „Zaun", „Anker", „Mast" | `alleSortiertNachBezeichnung()` | Reihenfolge: „Anker", „Mast", „Zaun" |
| TC-11 | F-12 | Produkt „Beratungsstunde" | `suche("BERATUNG")` | Trefferliste enthält „Beratungsstunde" (case-insensitive, Teilstring) |
| TC-12 | F-12 | Produkt `P-000042` | `suche("P-000042")` | Trefferliste enthält genau dieses Produkt |
| TC-13 | F-14 | Kein Produkt `P-999999` vorhanden | `findeProdukt("P-999999")` | liefert `null` |
| TC-14 | F-15 | 3 Produkte im Bestand | `exportiereCsv(ziel)` | CSV-Datei mit Kopfzeile + 3 Datenzeilen, Semikolon-getrennt, UTF-8 |
### 2.3 Komponente C — Kundenverwaltung
PH-Anf.-Nummern beziehen sich auf das Pflichtenheft Gruppe C. Die Schnittstelle
`KundenReferenzPruefung` (Gruppe A) wird durch einen Stub ersetzt.
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-01 | F-01, F-02 | Höchste Kundennummer `K-000016` | Kunde („Muster GmbH", „Hauptstr. 1", „68163", „Mannheim") speichern | Kunde persistiert; Kundennummer = `K-000017` |
| TC-02 | F-02 (Format) | Zähler = 7 | `naechsteNummer()` | liefert `K-000007` (führende Nullen, `String`) |
| TC-03 | F-03, NF-USE-01 | Kunde ohne Ort | `speichere()` | Speichern abgelehnt; Validierungsfehler benennt „Ort" |
| TC-04 | F-03 | Kunde mit leerem Namen (`""`) | `speichere()` | Speichern abgelehnt; Validierungsfehler benennt „Name" |
| TC-05 | F-04 | Kunde mit E-Mail `"max.mustermann"` | `speichere()` | Speichern abgelehnt (ungültiges E-Mail-Format) |
| TC-06 | F-04 | Kunde mit E-Mail `"max@beispiel.de"` | `speichere()` | Kunde gespeichert (gültiges Format) |
| TC-07 | F-05 | Kunde `K-000017` mit Ort „Mannheim" | Ort auf „Heidelberg" ändern, speichern | gespeicherter Kunde hat ort = „Heidelberg" |
| TC-08 | F-07 | Kunde `K-000017` | Änderungsversuch der Kundennummer auf `K-999999` | wirft `IllegalArgumentException` / Änderung abgelehnt |
| TC-09 | F-08 | Stub: `anzahlVerknuepfterDokumente``0` | `loescheKunde("K-000011")` mit Bestätigung | Kunde entfernt; nicht mehr in `alleSortiertNachName()` |
| TC-10 | F-09, F-10, GR-04 | Stub: `anzahlVerknuepfterDokumente("K-000010")``3` | `loescheKunde("K-000010")` | Löschen abgelehnt; Kunde weiterhin vorhanden; Hinweis enthält Anzahl `3` |
| TC-11 | F-11 | Kunden „Zimmer", „Albrecht", „Maier" | `alleSortiertNachName()` | Reihenfolge: „Albrecht", „Maier", „Zimmer" |
| TC-12 | F-12 | Kunde „Muster GmbH" | `suche("MUSTER")` | Trefferliste enthält „Muster GmbH" (case-insensitive, Teilstring) |
| TC-13 | F-12, F-14 | Kunde `K-000017` vorhanden; `K-999999` nicht | `suche("K-000017")`; `findeKunde("K-999999")` | Treffer enthält `K-000017`; `findeKunde` liefert `null` |
| TC-14 | F-15 | 3 Kunden im Bestand | `exportiereCsv(ziel)` | CSV-Datei mit Kopfzeile + 3 Datenzeilen, Semikolon-getrennt, UTF-8 |
### 2.4 Komponente D — Programmoberfläche
PH-Anf.-Nummern beziehen sich auf das Pflichtenheft Gruppe D. Getestet wird die GUI-freie
Controller- und Modell-Schicht; die Service-Schnittstellen der Gruppen AC werden durch
Stubs/Mocks ersetzt.
| TC | Abgedeckte PH-Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| TC-01 | F-09 | Wizard neu gestartet | `aktuellerSchritt` lesen | `KUNDE_WAEHLEN` (erster Schritt) |
| TC-02 | F-09 | Schritt 1 mit gewähltem Kunden | `weiter()` 4-mal mit gültigen Eingaben | Schrittfolge: `POSITIONEN_ERFASSEN``DATEN_BESTAETIGEN``ZUSAMMENFASSUNG``SPEICHERN` |
| TC-03 | F-10 | Schritt 1, kein Kunde gewählt (`kundenNr = null`) | `weiter()` | Wechsel verhindert; `Meldung(FEHLER, "Kunde", …)` erzeugt |
| TC-04 | F-10 | Schritt 2, leere Positionsliste | `weiter()` | Wechsel verhindert; Meldung benennt „Position" |
| TC-05 | F-10 | Schritt 2, Position mit `menge = 0` | `weiter()` | Wechsel verhindert; Meldung benennt „Menge" |
| TC-06 | F-11 | Schritt 3 erreicht; Kunde `K-000017`, 1 Position erfasst | `zurueck()` bis Schritt 1 | `kundenNr` und `positionen` unverändert erhalten |
| TC-07 | F-12 | Schritt 4; Stub `DokumentService` liefert Summen 200.00/38.00/238.00 | Zusammenfassung erzeugen | Zusammenfassung enthält Kunde, Positionen, Mengen, 200.00/38.00/238.00, Rechnungsdatum, Zahlungsziel |
| TC-08 | F-13 | Schritt 5; gültiges Modell | `speichern()` | genau **ein** Aufruf `erstelleRechnung(...)` am Mock; Erfolgsmeldung enthält gelieferte Rechnungsnummer |
| TC-09 | F-13 (Fehlerfall) | Stub `erstelleRechnung` wirft Validierungsfehler „Rechnungsdatum" | `speichern()` | keine Erfolgsmeldung; `Meldung(FEHLER, "Rechnungsdatum", …)` dargestellt (F-05/F-16) |
| TC-10 | F-14 | Dokumentliste mit Rechnungen in `OFFEN`, `VERSENDET`, `STORNIERT` | verfügbare Aktionen je Rechnung ermitteln | *Stornieren* nur bei Status `OFFEN` aktiviert |
| TC-11 | F-15 | Rechnung `R-2026-000124` | `storniere()` ohne Bestätigung; danach mit Bestätigung | ohne Bestätigung: kein Service-Aufruf; mit Bestätigung: genau ein Aufruf `storniere("R-2026-000124")` |
| TC-12 | F-08 | Beleg im Status `VERSENDET` | Änderungsaktionen ermitteln | alle inhaltlichen Änderungsaktionen deaktiviert; PDF-Export aktiviert |
| TC-13 | F-06 | Belege mit Status `OFFEN` (2×) und `STORNIERT` (1×) | Statusfilter `OFFEN` anwenden | Liste enthält genau die 2 offenen Belege |
| TC-14 | F-03 | Stub `KundenService.suche("Muster")` liefert 1 Treffer | Suchbegriff „Muster" eingeben | Controller delegiert an `KundenService.suche(...)`; Trefferliste enthält genau diesen Kunden |
| TC-15 | F-03 (D-F-03) | Stub `KundenService` mit 1 Kunden „Muster GmbH" | `kundenListe("")`, `(" ")`, `(null)`, `("Muster")`, `("unbekannt")` | leerer/fehlender Suchbegriff: gesamter Bestand (1); „Muster": 1 Treffer; „unbekannt": 0 Treffer |
### 2.5 Gemeinsame Infrastruktur (Paket `gemeinsam`)
Querschnittliche Dienste, die von allen Komponenten genutzt werden. Der `EreignisBus`
(Observer-Muster) ist in der Architektur der Komponente A (Pflichtenheft A §7) verortet;
`JsonPersistenz` ist die gemeinsame atomare JSON-Ablage hinter allen Repositories (IF-01).
#### 2.5.1 Ereignisbenachrichtigung (`EreignisBusTest`)
| TC | Abgedeckte Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| INF-01 | Observer (PH-A §7) | `EreignisBus` mit 2 Beobachtern für Bereich `KUNDEN` | `melde(KUNDEN)` 2× | beide Beobachter genau 2× benachrichtigt |
| INF-02 | Observer | Beobachter für `KUNDEN` und `DOKUMENTE` | `melde(DOKUMENTE)` | nur `DOKUMENTE`-Beobachter (1×); `KUNDEN`-Beobachter 0× |
| INF-03 | Observer (Robustheit) | `EreignisBus` ohne Beobachter | `melde(PRODUKTE)` | wirkungslos, keine Exception |
#### 2.5.2 Atomare JSON-Persistenz (`JsonPersistenzTest`)
| TC | Abgedeckte Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis |
|---------|------------|------------------------|----------------------|----------------------------|
| INF-04 | IF-01 (atomar) | leeres Verzeichnis | `schreibeAtomar(datei, ["a","b"])` | Zieldatei existiert; keine `.tmp`-Restdatei; Inhalt = `["a","b"]` |
| INF-05 | IF-01 | Datei mit Bestand `["alt"]` | `schreibeAtomar(datei, ["neu1","neu2"])` | Inhalt vollständig ersetzt = `["neu1","neu2"]` |
| INF-06 | IF-01 | Zielpfad mit fehlendem Unterordner | `schreibeAtomar(unterordner/datei, ["a"])` | fehlende Elternverzeichnisse angelegt; Datei existiert |
### 2.6 Performance-/Lastnachweise (`PerformanceTest`)
Übergreifende Lastnachweise gemäß Lastenheft. Referenzgröße: 5.000 Kunden, 5.000 Produkte,
1.000 Belege (vorab geseedet; das Befüllen fließt nicht in die Messung ein). Die Spalte
*Erwartetes Ergebnis* nennt die einzuhaltende Zeitschranke.
| ID | Abgedeckte Anf. | Vorbedingung | Eingabe | Erwartetes Ergebnis (Zeitschranke) |
|---------|------------|------------------------|--------------------|------------------------------|
| Q-04 | Q-04 (Start) | Seeding 5.000 Kunden / 5.000 Produkte / 1.000 Belege (je JSON) | drei Repositories laden | Laden in ≤ 5 s |
| Q-02 | Q-02 (Suche) | Bestand wie Q-04 | Kunden-/Produktsuche + Auflistung | abgeschlossen in ≤ 1 s |
| Q-03 | Q-03 (PDF) | Rechnung mit 50 Positionen | `exportiere(rechnung, ziel)` | PDF-Erstellung in ≤ 2 s |
| Q-08 | Q-08 (Export) | Bestand wie Q-04 | Vollexport Kunden + Produkte + Belege als CSV | abgeschlossen in ≤ 30 s |
## 3. Testumfang-Übersicht
| Testklasse | Komponente | Anzahl |
|------------|-----------|--------|
| `dokumente/DokumentzyklusTest` | A Prozess/Dokumentenzyklus | 13 |
| `dokumente/JsonDokumentRepositoryTest`| A Belegpersistenz (IF-01/GoBD) | 1 |
| `dokumente/PdfBoxPdfExporterTest` | A PDF-Export (F-15) | 3 |
| `dokumente/DokumentCsvExportTest` | A CSV-Export Belege (Q-08) | 1 |
| `produkte/ProduktVerwaltungTest` | B Produktverwaltung | 14 |
| `kunden/KundenVerwaltungTest` | C Kundenverwaltung | 14 |
| `gui/OberflaechenControllerTest` | D Programmoberfläche | 15 |
| `gemeinsam/EreignisBusTest` | Gemeinsame Infrastruktur (Observer) | 3 |
| `gemeinsam/JsonPersistenzTest` | Gemeinsame Infrastruktur (Persistenz) | 3 |
| `PerformanceTest` | Querschnitt (Q-02/Q-03/Q-04/Q-08) | 4 |
| **Summe** | | **71** |
Damit sind **71 Testfälle** über alle vier Komponenten, die gemeinsame Infrastruktur und die
Performance-Nachweise spezifiziert. Sie decken die funktionalen Kernregeln, die zentralen
Geschäftsregeln (GR-01…GR-06) sowie die Qualitäts-/Performanceanforderungen (Q-02, Q-03,
Q-04, Q-08, Q-09) ab.
## 4. Abkürzungen
| Abkürzung | Bedeutung | | Abkürzung | Bedeutung |
|-----------|-----------| |-----------|-----------|
| TC | Testfall (Test Case) | | TC | Testfall (Test Case) |
| F | Funktionale Anforderung (Pflichtenheft) | | INF | Infrastruktur-Testfall (Paket `gemeinsam`) |
| F | Funktionale Anforderung (Pflichtenheft, komponentenlokal) |
| NF | Nicht-funktionale Anforderung (Pflichtenheft) | | NF | Nicht-funktionale Anforderung (Pflichtenheft) |
| IF | Schnittstelle (Interface) |
| GR | Geschäftsregel (Lastenheft) | | GR | Geschäftsregel (Lastenheft) |
| Q | Qualitätsanforderung (Lastenheft) | | Q | Qualitätsanforderung (Lastenheft) |
| PH | Pflichtenheft | | PH | Pflichtenheft |
| CSV | Comma-Separated Values (offenes Exportformat) |
| GoBD | Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern |

BIN
Modultestplan.pdf 100644

Binary file not shown.

View File

@ -50,7 +50,7 @@ und den Modultest der Komponente *Prozess / Dokumentenzyklus*.
|---------|------------|-----------------------------|---------------------| |---------|------------|-----------------------------|---------------------|
| 1.0 | 09.06.2026 | Lucas Strubel | Initiale Erstellung | | 1.0 | 09.06.2026 | Lucas Strubel | Initiale Erstellung |
| 1.1 | 13.06.2026 | Lucas Strubel | Einfügen der UML-Diagramme (Klassen- und Sequenzdiagramm) | | 1.1 | 13.06.2026 | Lucas Strubel | Einfügen der UML-Diagramme (Klassen- und Sequenzdiagramm) |
| 1.2 | 15.06.2026 | Lucas Strubel | Modultestplan in eigenständiges Dokument (Modultestplan_GruppeA.md) ausgegliedert | | 1.2 | 15.06.2026 | Lucas Strubel | Modultestplan in eigenständiges Dokument (Modultestplan.md) ausgegliedert |
\newpage \newpage
@ -62,7 +62,7 @@ Auftragnehmers, **wie** die Komponente *Prozess / Dokumentenzyklus* der
Desktop-Fakturierungsanwendung die Anforderungen des Lastenhefts (v1.3) erfüllt. Es Desktop-Fakturierungsanwendung die Anforderungen des Lastenhefts (v1.3) erfüllt. Es
konkretisiert die fachlichen Anforderungen in testbare Systemanforderungen und dient als konkretisiert die fachlichen Anforderungen in testbare Systemanforderungen und dient als
direkte Grundlage für Design, Implementierung sowie den Komponenten- bzw. Modultestplan direkte Grundlage für Design, Implementierung sowie den Komponenten- bzw. Modultestplan
(eigenständiges Dokument *Modultestplan_GruppeA.md*). (eigenständiges Dokument *Modultestplan.md*).
### 1.2 Ziel ### 1.2 Ziel
Ziel dieses Pflichtenhefts ist die vollständige und testbare Spezifikation der Erzeugung, Ziel dieses Pflichtenhefts ist die vollständige und testbare Spezifikation der Erzeugung,
@ -286,7 +286,7 @@ erfolgt (Nachweis durch Netzwerk-Monitoring während eines repräsentativen Nutz
## 6. Daten und Schnittstellen ## 6. Daten und Schnittstellen
Dieses Kapitel ist direkter Input für den Modultestplan (eigenständiges Dokument *Modultestplan_GruppeA.md*). Datentypen werden Dieses Kapitel ist direkter Input für den Modultestplan (eigenständiges Dokument *Modultestplan.md*). Datentypen werden
bereits als Java-Typen angegeben. bereits als Java-Typen angegeben.
### 6.1 Datenobjekte und Datentypen ### 6.1 Datenobjekte und Datentypen
@ -369,7 +369,7 @@ exportieren (Q-08).
**Interne Schnittstellen:** Die Schnittstellen werden hier **fachlich** beschrieben **Interne Schnittstellen:** Die Schnittstellen werden hier **fachlich** beschrieben
(Zweck, ausgetauschte Daten, Richtung); konkrete Methodensignaturen (Zweck, ausgetauschte Daten, Richtung); konkrete Methodensignaturen
und Datentypen sind dem Komponentenentwurf bzw. dem Modultestplan (eigenständiges Dokument *Modultestplan_GruppeA.md*) vorbehalten. und Datentypen sind dem Komponentenentwurf bzw. dem Modultestplan (eigenständiges Dokument *Modultestplan.md*) vorbehalten.
*Genutzte Schnittstellen (Komponente A ruft auf):* *Genutzte Schnittstellen (Komponente A ruft auf):*