Aufgabenstellung - Überdeckung
Sachverhalt & Regel:
Dein Teamkollege hat einige Testfälle für das folgende Code-Stück erstellt.
Solange ein Kunde mehr als 50 € ausgibt, sollte der Versand kostenlos sein. Wenn es mehr als 25 € sind, aber weniger als 3 Artikel versendet werden müssen, sollte er ebenfalls kostenlos sein. Wenn es nur einen Artikel gibt, der mehr als 10 € kostet, sollte es einen Rabatt geben, aber der Versand sollte nicht kostenlos sein. In anderen Fällen sollte der volle Versandpreis gezahlt werden.
Er hat die folgenden Tests geschrieben und fragt dich, ob diese Testfälle den Code abdecken:
Code & Testfälle:
Code:
def is_shipping_free(price, numberOfItems, isPrimeShoppingMember):
print("Additional Statement 1")
if price > 50 or isPrimeShoppingMember:
print("Additional Statement 2")
if price > 25 and numberOfItems <3:
print("Additional Statement 3")
elif price > 10 and numberOfItems == 1 :
print("Additional Statement 4(discount)")
return False
return True
print("Additional Statement 5")
Gegebene Testfälle:
print("----------------")
is_shipping_free(30,2,True)
print("----------------")
is_shipping_free(15,1,False)
print("----------------")
is_shipping_free(15,1,True)
print("----------------")
is_shipping_free(50,1,False)
Aufgaben:
- Zeichne ein Zustandsübergangsdiagramm / einen gerichteten azyklischen Graph (DAG) für diesen Codeabschnitt
- Berechne die Anweisungsüberdeckung (Statement Coverage) und die Zweigüberdeckung (Branch Coverage)
- Berechne die Anweisungsüberdeckung und die Zweigüberdeckung, wenn die Zeile
print("Additional Statement 5")aus dem Code entfernt wird.
Lösung - Überdeckung
1. Zustandsübergangsdiagramm / gerichteter azyklischer Graph (DAG):
Grafik (DAG): Das Zustandsübergangsdiagramm als SVG liegt im Repo unter
02_Portfolio/QA_Lernwebseite/assets/ha3-svg/HA3-Teil2_DAG.svg.
is_shipping_free11 Kanten insgesamt (jede gezeichnete Kante einmal).
Knoten:
Start, S1, D1, S2, D2, S3, D3, S4,
Rückgaben (über return True / return False).
2. Anweisungsüberdeckung (Statement Coverage) und
Zweigüberdeckung (Branch Coverage):
Zuordnung: Statement-Indizes
Die folgenden Indizes 1–10 entsprechen der Auszählung in der Lösung (ohne die Zeile def …); sie ordnen die Ausführungspfad-Tabellen unten dem Code zu.
| Index | Element im Code |
|---|---|
| 1 | print("Additional Statement 1") |
| 2 | if price > 50 or isPrimeShoppingMember: |
| 3 | print("Additional Statement 2") |
| 4 | if price > 25 and numberOfItems <3: |
| 5 | print("Additional Statement 3") |
| 6 | elif price > 10 and numberOfItems == 1 : |
| 7 | print("Additional Statement 4(discount)") |
| 8 | return False |
| 9 | return True |
| 10 | print("Additional Statement 5") — unerreichbar (toter Code nach return True) |
Anweisungsüberdeckung (Statement Coverage)
| Test | Parameter (price, numberOfItems, isPrime) |
Ausgeführte Statement-Indizes |
|---|---|---|
| T1 | (30, 2, True) | 1, 2, 3, 4, 5, 9 |
| T2 | (15, 1, False) | 1, 2, 4, 6, 7, 8 |
| T3 | (15, 1, True) | 1, 2, 3, 4, 6, 7, 8 |
| T4 | (50, 1, False) | 1, 2, 4, 5, 9 |
Über alle vier Tests hinweg werden die Anweisungen mit den Indizes 1–9 jeweils mindestens einmal durchlaufen. Index 10 taucht in keinem Test auf: die zugehörige Zeile steht im Code nach return True und ist damit unerreichbar. Die Vereinigung aller über die Tests ausgeführten Anweisungen ist also genau {1, …, 9} — ohne den Index 10.
Statement Coverage: 9 / 10 = 90 %
Zweigüberdeckung (Branch Coverage)
| Kante | Von Testfällen abgedeckt? |
|---|---|
| Start → S1 | alle vier |
| S1 → D1 | alle vier |
| D1 → S2 (True) | T1, T3 |
| D1 → D2 (False, ohne S2) | T2, T4 |
| S2 → D2 | T1, T3 |
| D2 → S3 (True) | T1, T4 |
| D2 → D3 (False) | T2, T3 |
S3 → return True | T1, T4 |
| D3 → S4 (True) | T2, T3 |
D3 → return True (False-Zweig des elif) | fehlt |
S4 → return False | T2, T3 |
Für jede der 11 Kanten steht in der Tabelle, welche der vier Tests sie durchlaufen — so lässt sich die Zweigabdeckung ablesen.
Fehlender Zweig: Kante D3 → return True (z. B. abdeckbar mit (15, 2, False) — Rabattpfad ausgeschlossen, aber kein kostenloser Versand über die zweite if-Bedingung).
Branch Coverage: 10 / 11 ≈ 90,91 %
3. Wenn die Zeile print("Additional Statement 5") entfernt wird:
| Metrik | Ergebnis |
|---|---|
| Statement Coverage | 9 ausführbare Anweisungen, alle 9 werden von den vier Tests erreicht → 9 / 9 = 100 % |
| Branch Coverage | unverändert 10 / 11 ≈ 90,91 % — die entfernte Zeile war keine zusätzliche Kante im Graph |
Begründung:
- Anweisungsüberdeckung: Anteil der ausführbaren Anweisungen (bzw. hier der vereinbarten Indizes), die mindestens ein Test ausführt.
- Zweigüberdeckung (ISTQB): Alle Kanten des Kontrollflussgraphen (DAG) — nicht nur die Booleschen Entscheidungen isoliert.
- Der fehlende Pfad D3 →
return Trueerklärt eine nicht getestete Kante von 11.