Code Coverage: Unterschied zwischen den Versionen
Markierung: Zurückgesetzt |
|||
| (9 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
'''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 == | |||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
| Zeile 18: | Zeile 22: | ||
Dieser Code hat zwei unabhängige if-Bedingungen: eine für x und eine für y. | Dieser Code hat zwei unabhängige if-Bedingungen: eine für x und eine für y. | ||
== | == Anweisungsüberdeckung (Statement Coverage) == | ||
Anweisungsüberdeckung bedeutet, dass '''jede''' Anweisung im Code mindestens einmal ausgeführt wird. In diesem Beispiel sind die Anweisungen: | 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. | Das Ziel der Anweisungsüberdeckung ist es, sicherzustellen, dass jede dieser Anweisungen mindestens einmal aufgerufen wird. | ||
| Zeile 43: | Zeile 47: | ||
* Ebenso wird die Bedingung y > 0 erfüllt, also wird System.out.println("y ist positiv") ausgeführt. | * Ebenso wird die Bedingung y > 0 erfüllt, also wird System.out.println("y ist positiv") ausgeführt. | ||
== | == Zweigüberdeckung (Branch Coverage) == | ||
Zweigüberdeckung bedeutet, dass jeder Zweig einer Bedingung '''mindestens einmal''' getestet wird (true und false). | Zweigüberdeckung bedeutet, dass jeder Zweig einer Bedingung '''mindestens einmal''' getestet wird (true und false). | ||
| Zeile 59: | Zeile 63: | ||
Damit sind alle Zweige (true/false) beider Bedingungen abgedeckt. | Damit sind alle Zweige (true/false) beider Bedingungen abgedeckt. | ||
== | == Pfadüberdeckung (Path Coverage) == | ||
Pfadüberdeckung bedeutet, dass '''alle möglichen Kombinationen''' von Pfaden durch den Code getestet werden. | Pfadüberdeckung bedeutet, dass '''alle möglichen Kombinationen''' von Pfaden durch den Code getestet werden. | ||
| Zeile 66: | Zeile 70: | ||
# x > 0 und y > 0 | # x > 0 und y > 0 | ||
# x > 0 und y <= 0 | # x > 0 und y <= 0 | ||
# x <= 0 und y > 0 | # x <= 0 und y > 0 | ||
# x <= 0 und y <= 0 | # x <= 0 und y <= 0 | ||
| Zeile 83: | Zeile 84: | ||
Mit diesen vier Testfällen decken wir alle möglichen Pfade durch den Code ab. | 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. | * '''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. | * '''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. | ||
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 | |||
== Äquivalenzklassen == | |||
Die '''Äquivalenzklassenbildung''' ist ein Testverfahren, bei dem Eingabewerte in Gruppen (Klassen) eingeteilt werden. | |||
Alle Werte einer Klasse verhalten sich aus Sicht des Programms gleich, sodass es ausreicht, nur einen repräsentativen Wert pro Klasse zu testen. | |||
=== Ziel === | |||
* Reduzierung der Anzahl an Testfällen | |||
* trotzdem gute Testabdeckung | |||
* systematisches Testen von Eingaben | |||
=== Anwendung auf das Beispiel === | |||
Die Funktion prüft die Bedingungen: | |||
* x > 0 | |||
* y > 0 | |||
Daraus ergeben sich folgende Äquivalenzklassen: | |||
'''Für x:''' | |||
* x > 0 (gültig) | |||
* x ≤ 0 (nicht positiv) | |||
'''Für y:''' | |||
* y > 0 (gültig) | |||
* y ≤ 0 (nicht positiv) | |||
=== Testfälle aus Äquivalenzklassen === | |||
Aus den Klassen lassen sich sinnvolle Testfälle ableiten: | |||
<syntaxhighlight lang="java"> | |||
Beispiel.beispielFunktion(1, 1); // beide positiv | |||
Beispiel.beispielFunktion(1, -1); // x positiv, y nicht | |||
Beispiel.beispielFunktion(-1, 1); // x nicht, y positiv | |||
Beispiel.beispielFunktion(-1, -1); // beide nicht positiv | |||
</syntaxhighlight> | |||
=== Zusammenhang zur Pfadüberdeckung === | |||
Die Äquivalenzklassen führen in diesem Beispiel direkt zu den gleichen Testfällen wie die '''Pfadüberdeckung'''. | |||
Allerdings ist die Methode allgemeiner und wird vor allem zur Planung von Testfällen verwendet. | |||
=== Kurzmerksatz === | |||
'''Äquivalenzklassen fassen ähnliche Eingaben zusammen, sodass weniger, aber gezielte Testfälle benötigt werden.''' | |||
== 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. | * '''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:''' Du benötigst 4 Testfälle, um alle Kombinationen der Bedingungen (also alle Pfade) zu testen. | ||
Aktuelle Version vom 7. April 2026, 08:50 Uhr
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.
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.
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.
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.
Äquivalenzklassen
Die Äquivalenzklassenbildung ist ein Testverfahren, bei dem Eingabewerte in Gruppen (Klassen) eingeteilt werden. Alle Werte einer Klasse verhalten sich aus Sicht des Programms gleich, sodass es ausreicht, nur einen repräsentativen Wert pro Klasse zu testen.
Ziel
- Reduzierung der Anzahl an Testfällen
- trotzdem gute Testabdeckung
- systematisches Testen von Eingaben
Anwendung auf das Beispiel
Die Funktion prüft die Bedingungen:
- x > 0
- y > 0
Daraus ergeben sich folgende Äquivalenzklassen:
Für x:
- x > 0 (gültig)
- x ≤ 0 (nicht positiv)
Für y:
- y > 0 (gültig)
- y ≤ 0 (nicht positiv)
Testfälle aus Äquivalenzklassen
Aus den Klassen lassen sich sinnvolle Testfälle ableiten:
Beispiel.beispielFunktion(1, 1); // beide positiv
Beispiel.beispielFunktion(1, -1); // x positiv, y nicht
Beispiel.beispielFunktion(-1, 1); // x nicht, y positiv
Beispiel.beispielFunktion(-1, -1); // beide nicht positiv
Zusammenhang zur Pfadüberdeckung
Die Äquivalenzklassen führen in diesem Beispiel direkt zu den gleichen Testfällen wie die Pfadüberdeckung. Allerdings ist die Methode allgemeiner und wird vor allem zur Planung von Testfällen verwendet.
Kurzmerksatz
Äquivalenzklassen fassen ähnliche Eingaben zusammen, sodass weniger, aber gezielte Testfälle benötigt werden.
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.
