Zum Inhalt
wannacode

Codeüberdeckung

Kurz gesagt: Die Anweisungsüberdeckung fragt, ob jede Codezeile gelaufen ist. Die Zweigüberdeckung fragt, ob jede Entscheidung in beide Richtungen gegangen ist. Bei der Lieferfunktion braucht die erste 2 Tests, die zweite 3. 100 % Zweigüberdeckung schließen 100 % Anweisungsüberdeckung ein, aber nicht umgekehrt. Und keine Überdeckung sagt, dass das Ergebnis geprüft wurde oder dass die Grenze an der richtigen Stelle liegt.

Problem

100 % Überdeckung, eine falsche Gebühr

Der Entwickler lässt die Lieferungstests mit einem Werkzeug laufen, das zählt, welche Zeilen gelaufen sind. Die Tests sind zwei: 0 € und 60 €. Der Bericht sagt: 100 % der Zeilen.

Am nächsten Tag zahlen Kunden mit einem Warenkorb von 30 € 4,99 € Lieferkosten statt 4,90 €. Die Zeile mit der Gebühr ist gelaufen. Kein Test hat gesehen, was darin stand.

Die Idee

Die Whitebox

Bisher kamen die Tests aus der Regel: Das ist die Blackbox. Whitebox-Verfahren nehmen die Tests aus dem Code: welche Zeilen er hat und welche Pfade das Programm nehmen kann.

Für diese Lektion musst du keinen Code schreiben können. Du musst die Lieferfunktion lesen können. Die Sprache wählst du selbst, in den Tabs:

static String delivery(double total) {
if (total <= 0) {
return "abgelehnt";
}
double fee = 4.90;
if (total >= 50) {
fee = 0;
}
return String.format("%.2f €", fee);
}

Die Funktion hat zwei Entscheidungen (Stellen, an denen das Programm einen Pfad wählt): „der Warenkorbwert ist 0 oder weniger“ und „der Warenkorbwert ist 50 oder mehr“. Die zweite ist ein „if“ ohne „else“: Wenn sie falsch ist, überspringt das Programm einfach die Zeile, die die Gebühr auf null setzt.

Die Idee

Anweisungsüberdeckung

Die Anweisungsüberdeckung fragt: Wie viele der Zeilen, die etwas tun, hat mindestens ein Test ausgeführt?

Hier sind die zwei Tests vom Anfang als Aufrufe der Funktion, mit ihrer Ausgabe:

System.out.println("0 € → " + delivery(0));
System.out.println("60 € → " + delivery(60));
Ausgabe
0 € → abgelehnt
60 € → 0.00 €
  • 0 € geht durch die erste Prüfung und gibt „abgelehnt“ zurück.
  • 60 € geht durch alles andere: Die Gebühr wird 4,90, dann macht die Prüfung „ab 50“ sie zu 0, dann die Rückgabe.

Jede Zeile ist gelaufen. Die Anweisungsüberdeckung beträgt 100 %, mit zwei Tests.

Die Idee

Zweigüberdeckung

Die Zweigüberdeckung fragt etwas anderes: Ist jede Entscheidung in beide Richtungen gegangen?

Hier gibt es vier Zweige: die erste Prüfung wahr und falsch, die zweite wahr und falsch. 0 € nimmt die erste als wahr. 60 € nimmt die erste als falsch und die zweite als wahr. Niemand nimmt die zweite als falsch: Das ist der leere Pfad eines „if“ ohne „else“. Die Überdeckung ist 3 von 4, also 75 %.

Ein dritter Test, mit kostenpflichtiger Lieferung, schließt die Lücke:

System.out.println("0 € → " + delivery(0));
System.out.println("30 € → " + delivery(30));
System.out.println("60 € → " + delivery(60));
Ausgabe
0 € → abgelehnt
30 € → 4.90 €
60 € → 0.00 €

Drei Tests, 100 % der Zweige. Und die Antwort auf die Frage der Lektion: 100 % Zweigüberdeckung der Lieferfunktion brauchen 3 Tests.

Genauer, für Neugierige

Der ISTQB CTFL v4.0.1 beschreibt beide Maße in Abschnitt 4.3: Anweisungstest und Zweigtest. Die Überdeckung ist die Anzahl der ausgeführten Anweisungen (oder genommenen Zweige) im Verhältnis zu allen, in Prozent. Der Lehrplan nennt auch ihr Verhältnis: 100 % Zweigüberdeckung schließen 100 % Anweisungsüberdeckung ein, aber nicht umgekehrt.

Es gibt auch strengere Maße: die Bedingungsüberdeckung (jede Bedingung in einer Entscheidung wurde wahr und falsch gesehen) und MC/DC (jede Bedingung hat gezeigt, dass sie allein die Entscheidung ändern kann). MC/DC wird für die kritischste Software in der Luftfahrt verlangt. Im CTFL v4.0 stehen sie nicht.

Die Überdeckung wird mit einem Werkzeug gemessen: JaCoCo für Java, coverlet für C#, coverage.py für Python, c8 oder das in Node eingebaute für JavaScript. Die Tests laufen, und das Werkzeug markiert, welche Zeilen und Zweige genommen wurden.

Probier es aus

Wie viele Tests?

1. Ein Test mit einem Warenkorb von 0 €. Welche Teile der Funktion führt er aus?
2. Die Tests sind 0 € und 60 €. Wie hoch ist die Zweigüberdeckung?
3. Welcher Test bringt die Zweigüberdeckung auf 100 %?

Die Idee

Warum 100 % Anweisungen die Gebühr übersahen

Hier ist die Funktion vom Anfang, mit der Gebühr 4,99:

static String delivery(double total) {
if (total <= 0) {
return "abgelehnt";
}
double fee = 4.99;
if (total >= 50) {
fee = 0;
}
return String.format("%.2f €", fee);
}

Mit den zwei Anweisungstests ist die Ausgabe dieselbe wie bei der richtigen Funktion:

System.out.println("0 € → " + delivery(0));
System.out.println("60 € → " + delivery(60));
Ausgabe
0 € → abgelehnt
60 € → 0.00 €

Bei 60 € läuft die Zeile mit der Gebühr, aber gleich danach wird die Gebühr 0. Der falsche Wert erreicht die Ausgabe nie. Gelaufen heißt nicht geprüft.

Der dritte Test, der für die volle Zweigüberdeckung, nimmt den leeren Pfad und zeigt die Gebühr:

System.out.println("0 € → " + delivery(0));
System.out.println("30 € → " + delivery(30));
System.out.println("60 € → " + delivery(60));
Ausgabe
0 € → abgelehnt
30 € → 4.99 €
60 € → 0.00 €

Deshalb ist die Zweigüberdeckung stärker. Der leere Pfad eines „if“ ist genau die Stelle, an der ein Wert aus der Zeile darüber den Kunden erreicht.

Die Idee

Was Überdeckung nicht sagt

Hier ist die Prüfung des Warenkorb-Limits: Das Hinzufügen wird abgelehnt, wenn es weniger als 1 Stück ist oder wenn der Warenkorb mehr als 10 enthalten würde.

static boolean canAdd(int inCart, int add) {
if (add < 1 || inCart + add > 10) {
return false;
}
return true;
}

Zwei Aufrufe geben 100 % der Zweige: (5, 0) geht durch „abgelehnt“, (2, 3) durch „angenommen“.

System.out.println(canAdd(5, 0));
System.out.println(canAdd(2, 3));
Ausgabe
false
true

Ändere jetzt „> 10“ zu „> 11“. Dieselben zwei Tests bestehen, die Überdeckung ist immer noch 100 %, und das 11. Stück kommt in den Warenkorb. Die Überdeckung misst, was gelaufen ist, nicht wie nah an der Grenze. Der Test (10, 1) aus der Lektion über Grenzwerte fängt den Fehler.

Und etwas, das keine Überdeckung sehen kann: fehlender Code. Wenn die Prüfung auf einen leeren Warenkorb nie geschrieben wurde, bleibt keine Zeile ungedeckt. 100 % Überdeckung von Code, der nicht tut, was gebraucht wird, sind immer noch 100 %. Deshalb ersetzt die Whitebox die Blackbox nicht. Überdeckung sagt, wo es keine Tests gibt, nicht dass die Tests gut sind.

Übung

Die Überdeckung des Limits

1. Zwei Bedingungen, eine Entscheidung. Die Fragen gehen um die Limitprüfung oben.

1. Wie viele Tests braucht 100 % Zweigüberdeckung der Limitprüfung?
2. Im Code wird „> 10“ zu „> 11“ geändert. Geben die Tests (5, 0) und (2, 3) 100 % Zweigüberdeckung?
3. Wird mit den Tests (5, 0) und (2, 3) der Teil „der Warenkorb plus das Hinzugefügte ist über 10“ überhaupt ausgewertet?

Test

Teste dich

1. Woher kommen die Tests bei Whitebox-Verfahren?
2. Was stimmt?
3. Die Tests ergeben 100 % Anweisungsüberdeckung, und eine Gebühr von 4,99 € statt 4,90 € rutscht durch. Warum?
4. Was kann keine Codeüberdeckung sagen?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·