Code Coverage
Code Coverage in Java
Code Coverage (Testabdeckung) gibt an, wie viel Prozent des Programmcodes während eines Tests tatsächlich ausgeführt wurde. Sie misst also, wie gut der vorhandene Code durch Tests abgedeckt ist und hilft einzuschätzen, ob wichtige Teile des Programms ausreichend getestet wurden.
Eine hohe Code Coverage bedeutet nicht automatisch fehlerfreie Software, zeigt aber, dass viele Wege im Programm getestet wurden. Typische Messgrößen sind Anweisungsüberdeckung, Zweigüberdeckung und Pfadüberdeckung.
Beispielcode
public class Beispiel {
public static void beispielFunktion(int x, int y) {
if (x > 0) {
System.out.println("x ist positiv");
}
if (y > 0) {
System.out.println("y ist positiv");
}
}
}
Dieser Code hat zwei unabhängige if-Bedingungen: eine für x und eine für y.
1. Anweisungsüberdeckung (Statement Coverage)
Anweisungsüberdeckung bedeutet, dass jede Anweisung im Code mindestens einmal ausgeführt wird. In diesem Beispiel sind die Anweisungen:
Bedingung 1: if (x > 0)
Anweisung 1: System.out.println("x ist positiv");
Bedingung 2: (y > 0)
Anweisung 2: System.out.println("y ist positiv");
Das Ziel der Anweisungsüberdeckung ist es, sicherzustellen, dass jede dieser Anweisungen mindestens einmal aufgerufen wird.
Testfall für 100% Anweisungsüberdeckung:
Beispiel.beispielFunktion(1, 1); // x > 0, y > 0
Erklärung:
- Bei beispielFunktion(1, 1) wird die Bedingung x > 0 erfüllt, also wird System.out.println("x ist positiv") ausgeführt.
- Ebenso wird die Bedingung y > 0 erfüllt, also wird System.out.println("y ist positiv") ausgeführt.
2. Zweigüberdeckung (Branch Coverage)
Zweigüberdeckung bedeutet, dass jeder Zweig einer Bedingung mindestens einmal getestet wird (true und false).
- if (x > 0): true / false
- if (y > 0): true / false
Testfälle für 100% Zweigüberdeckung:
Beispiel.beispielFunktion(-1, 1); // x <= 0, y > 0
Beispiel.beispielFunktion(1, -1); // x > 0, y <= 0
Damit sind alle Zweige (true/false) beider Bedingungen abgedeckt.
3. Pfadüberdeckung (Path Coverage)
Pfadüberdeckung bedeutet, dass alle möglichen Kombinationen von Pfaden durch den Code getestet werden.
Mögliche Pfade:
- x > 0 und y > 0
- x > 0 und y <= 0
- x <= 0 und y > 0
- x <= 0 und y <= 0
Testfälle für 100% Pfadüberdeckung:
Beispiel.beispielFunktion(1, 1); // Pfad 1
Beispiel.beispielFunktion(1, -1); // Pfad 2
Beispiel.beispielFunktion(-1, 1); // Pfad 3
Beispiel.beispielFunktion(-1, -1); // Pfad 4
Mit diesen vier Testfällen decken wir alle möglichen Pfade durch den Code ab.
Unterschied zwischen Zweig- und Pfadüberdeckung
- Zweigüberdeckung prüft nur, ob jeder Zweig der Bedingung (z.B. if- oder else-Zweig) mindestens einmal durchlaufen wurde. Die Testfälle für Zweigüberdeckung beispielFunktion(-1, 1), beispielFunktion(1, -1)) erreichen dies.
- Pfadüberdeckung geht einen Schritt weiter und stellt sicher, dass jede Kombination der Bedingungen getestet wird. Hier sind zwei zusätzliche Testfälle (beispielFunktion(-1, -1), beispielFunktion(1, 1)) notwendig, um den Pfad x <= 0 und y <= 0 , sowie x >= 0 und y >= 0 zu testen. Diese Pfade werden bei der reinen Zweigüberdeckung nicht getestet.
Fazit
- Anweisungsüberdeckung: 1 Testfall reicht aus, wenn alle Anweisungen mindestens einmal ausgeführt werden (z. B. beispielFunktion(1, 1))
- Zweigüberdeckung: Du kannst 100% Zweigüberdeckung mit 2 Testfällen erreichen, da beide Zweige jeder Bedingung (true/false) getestet werden.
- Pfadüberdeckung: Du benötigst 4 Testfälle, um alle Kombinationen der Bedingungen (also alle Pfade) zu testen.
Pfadüberdeckung ist strenger, da sie jede mögliche Ausführungskombination abdeckt.
