Code Coverage dient den meisten Software-Entwicklern als die wichtigste Metrik für die Vollständigkeit von Software-Tests.
Inhaltsübersicht |
---|
1. Varianten des Code Coverage » |
2. Regulatorische Anforderungen » |
3. Bewertung der Code Coverage » |
4. Bestimmen der Code Coverage » |
1. Was Code Coverage ist
Code Coverage übersetzt man meist mit Abdeckungsgrad, Testabdeckung oder Code-Abdeckung. Diese Maßzahl gibt das Verhältnis von tatsächlich durchgeführten Tests und den theoretisch möglichen Tests an.
Abhängig davon, wie man die Anzahl theoretisch möglicher Tests bestimmt, unterscheidet man zwischen Statement Coverage, Branch Coverage, Decision Coverage und weiteren Abdeckungsgraden.
a) Statement Coverage – Anweisungsabdeckung
Die Anweisungsabdeckung (englisch: Statement Coverage) entspricht den beim Test durchlaufenen Anweisungen im Verhältnis zu allen Anweisungen. Beispiele für Anweisungen wären Wertezuweisungen bei Variablen, Fallunterscheidungen, Schleifen und Methodenaufrufe. Bei vielen Programmiersprachen ist es gute Praxis, pro Code-Zeile (nur) eine Anweisung zu schreiben.
Beispiel
Ruft man in diesem Beispiel die Methode einmal mit den Werten (23, 80) und einmal mit den Werten (160, 80) auf, so werden nicht alle Zeilen durchlaufen: Rot steht für nicht durchlaufene Zeilen und grün für durchlaufene Zeilen. Über die gelben sprechen wir gleich.
Die Anweisungsabdeckung zählt zu den schwachen Abdeckungsgraden.
b) Branch Coverage – Zweigabdeckung
Ein stärkerer Abdeckungsgrad ist die Zweigabdeckung. Sie entspricht dem Verhältnis der beim Test durchlaufenen Zweige (auch Kanten genannt). Was ein Zweig bzw. eine Kante ist, lässt sich am Beispiel eines Programmgrafs (passend zum obigen Code-Ausschnitt) verstehen.
Wenn die in Abb. 1 gezeigte Funktion mit den Werten (23, 80), (160, 80), (180, 40) und (160, 60) aufgerufen wird, werden zwar alle Anweisungen durchlaufen, aber nicht alle Zweige. In unserem Beispiel fehlt der Zweig, der die Anweisungen 11 und 15 verbindet (Abb. 2).
Eine 100%ige Zweigabdeckung bedingt eine 100%ige Anweisungsabdeckung. Das Umgekehrte gilt nicht. Damit ist die Zweigabdeckung das stärkere Maß und nicht die Anweisungsabdeckung.
c) Condition Coverage – Bedingungsabdeckung
Viele Bedingungen (if-Bedingungen, Schleifenköpfe) bestehen aus Teilbedingungen. In unserem Beispiel enthält die Bedingung in Zeile 6 insgesamt vier atomare Teilbedingungen.
Die Zweigabdeckung unterscheidet nicht, aufgrund welcher Teilbedingungen eine Bedingung als wahr oder falsch ausgewertet wird. Dies erreicht die Bedingungsabdeckung. Man unterscheidet dabei zwischen der Einfach- und der Mehrfachbedingungsabdeckung.
Einfachbedingungsabdeckung
Die Einfachbedingungsabdeckung gibt den Anteil der atomaren Teilbedingungen an, die mindestens einmal den Wert wahr und mindestens einmal den Wert falsch angenommen haben.
Eine 100%ige Einfachbedingungsabdeckung führt nicht zu 100%iger Zweigabdeckung, wie folgendes Beispiel zeigt:
Gesamtbedingung = (Teilbedingung_1 OR Teilbedingung_2)
Testfälle
- Teilbedingung_1 = wahr, Teilbedingung_2 = falsch (nicht erfüllt)
- Teilbedingung_1 = falsch, Teilbedingung_2 = wahr (erfüllt)
Obwohl jede der beiden Teilbedingungen einmal erfüllt und einmal nicht erfüllt war, wurde die Gesamtbedingung immer als „wahr“ ausgewertet. Das heißt, der Test führte den „falsch-Zweig“ nie aus.
Mehrfachbedingungsabdeckung
Bei der Mehrfachbedingungsabdeckung werden die Testfälle so gewählt, dass alle Kombinationen dieser Bedingungen getestest werden. Bei vier atomaren Teilbedingungen (wie im obigen Beispiel) bedarf es somit mindestens 42 = 16 Testfälle. Für 5 Teilbedingungen wären es 32 Testfälle, da der Anzahl 2n ist, wobei n die Anzahl der Teilbedingungen angibt.
d) Weitere Code-Coverage-Maße
Zu den weiteren Abdeckungsgraden zählen die Schleifenabdeckung und die Pfadabdeckung.
Bitte beachten Sie auch den Artikel zum kombinatorischen Testen, der weitere „Coverage-Grade“ einführt, die sich sogar für Blackbox-Tests eigenen.
2. Regulatorische Anforderungen an das Code Coverage
In vielen regulierten Branchen wie der Flugzeugindustrie oder der Medizintechnik gibt es normative Anforderungen. Sie finden diese am Beispiel der Medizintechnik hier vorgestellt.
a) Europa
Immerhin kennt die IEC 62304 (Version 1.1) den Begriff Code Coverage. Die Norm fordert aber nicht, dass diese Metrik überhaupt erhoben wird. Sie empfiehlt aber im nicht-normativen Teil, die Code Coverage zu erhöhen.
Ein Auditor kann somit keine Nicht-Konformität bescheinigen, wenn Sie die Code Coverage nicht bestimmen. Er oder sie kann aber durchaus eine Begründung verlangen, weshalb man die Festlegung und die Überprüfung der Akzeptanzkriterien für eine Software-Einheit als ausreichend vollständig betrachtet.
b) USA, FDA
Die Forderungen
Die FDA geht auf die Code Coverage im Guidance Document General Principles of Software Validation ein. Sie schreibt:
„Measures such as […] testing coverage […] are all used to develop an acceptable level of confidence before shipping the product.“
Die FDA diskutiert die verschiedenen Abdeckungsgrade und stellt fest:
„It [Decision Coverage] is considered to be a minimum level of coverage for most software products, but decision coverage alone is insufficient for high-integrity applications.“
Dabei versteht die FDA unter „Coverage“ eine 100%ige Abdeckung – gleich für welchen Typ an Abdeckungsgrad.
Die Realität
Wir haben in unserer langjährigen Beratungspraxis keinen Medizinproduktehersteller kennengelernt, der Produkte in den USA zugelassen und eine 100%ige Code-Abdeckung erreicht hat. Wir haben sehr selten Fälle erlebt, in denen ein FDA Inspektor dies thematisierte.
Wie Sie vorgehen können, um diesbezüglich Schwierigkeiten bei FDA-Inspektionen zu vermeiden, lesen Sie weiter unten.
3. Kritische Bewertung der Code Coverage
a) Vorteile
Ein Hersteller kann ohne „ausreichendes“ Testen nicht vermuten, dass seine Software ausreichend fehlerfrei ist. Eine notwendige (aber nicht hinreichende) Voraussetzung für die Annahme, dass das Testen „ausreichend“ ist, besteht darin, dass der Code beim Testen überhaupt (vollständig) durchlaufen wird.
Die Abdeckungsgrade sind eine (Dank Werkzeugen) einfach zu erhebende, quantitative Metrik für die Vollständigkeit von Tests. Damit können Entwickler, Führungskräfte und Auditoren erkennen, welche Teile der Software intensiver getestet werden müssen.
b) Nachteile
Beim Bestimmen der Code Coverage sollten Sie beachten:
- Source Code notwendig
Eine Voraussetzung stellt der Source Code dar. Bibliotheken und kompilierte Artefakte können zwar als Blackbox getestet werden, die Abdeckungsgrade lassen sich aber meist nicht bestimmen. - Nicht vollständig testbar
Ebenso widersetzen sich Teile des Codes wie sehr hardwarenahe Anweisungen dem Testen und damit dem Bestimmen der Code Coverage. - Kein Korrektheitsbeweis
Selbst eine vollständige Testabdeckung von 100 % Decision Coverage stellt keinen Korrektheitsbeweis der Software dar. Dazu müssten alle möglichen Inputwerte getestet werden, was kombinatorisch in fast allen Fällen unmöglich ist. - Aufwand
Das Aufsetzen der Werkzeuge zum Bestimmen der Code Coverage bedeutet einen (einmaligen) Aufwand. Das Schreiben des Tests ebenso. - Timing-Verhalten
Werkzeuge verändern den Source Code z.B. dadurch, dass sie Zählen einfügen. Diese Instrumentierung kann das Timing-Verhalten ändern und dadurch ggf. Fehler maskieren, die ohne die Instrumentierung sichtbar wären. - Werkzeugunterstützung
Die marktüblichen Werkzeuge erlauben es nicht, alle der o.g. Varianten der Testabdeckung zu bestimmen (was auch nicht immer notwendig ist).
4. Tipps zum Bestimmen der Code Coverage
Eine Software-Entwicklung, die den Anspruch der Professionalität erhebt, wird auf das Bestimmen der Code Coverages nicht verzichten. Daher folgen einige Tipps.
a) Integration im Entwicklungsprozess
Legen Sie in der entsprechenden Verfahrensanweisung, der Arbeitsanweisung oder im Software-Entwicklungsplan fest, welche Variante der Code Coverage zu welchem Grad erreicht werden muss. Fordern Sie auch, dass die Unit-Tests parallel zum Code entwickelt werden und nicht erst am Ende der Software-Entwicklung.
b) Umgang mit altem Code
Damit Sie sich mit altem Code nicht übernehmen, können Sie fordern, dass (nur) jede neue und jede geänderte Methode zu testen und damit die Code Coverage zu bestimmen ist.
Alternativ können Sie mit sehr niedrigen Zielwerten starten und diese im Lauf der Zeit langsam erhöhen.
c) Risikobasierter Ansatz
Wenn Sie mit weniger als 100 % arbeiten, dann bestimmen Sie die Abdeckungsgrade für verschiedene Komponenten unterschiedlich, z.B. abhängig von
- der Sicherheitsklasse (d.h. dem maximalen Schaden, den ein Fehler verursachen würde),
- der Bewährtheit der Komponente oder
- der Komplexität der Komponente, die Sie mit dem McCabe-Maß quantifizieren.
Im letzteren Fall ließe sich beispielsweise fordern, dass für alle Methoden mit einer zyklomatischen Komplexität (McCabe-Maß) von acht oder größer die Zweigabdeckung 100 % betragen muss. Bei Methoden mit einer Komplexität von drei bis sieben muss eine Zweigabdeckung von über 50 % erreicht werden.
d) Refactoring
Eine häufig genannte Begründung für niedrige Coverage-Grade lautet, dass sich der Code überhaupt nicht testen ließe. Das ist ein starkes Indiz für eine schlechte Architektur, z.B. für einen fehlenden Hardware Abstraction Layer (HAL) oder für Komponenten, die nicht funktional gebildet sind. Nutzen Sie diese niedrigen Testabdeckungen als Indikator dafür, wo ein Refactoring notwendig ist.
e) Werkzeuge
Vergessen Sie nicht, das Code-Coverage-Werkzeug in Ihre Liste der zu validierenden Werkzeuge aufzunehmen. Das bedingt, dass Sie das Werkzeug einschließlich der Konfigurationsdateien unter Versionskontrolle halten, ggf. auf allen Entwickler-Maschinen.
Sie finden hier eine Liste von Werkzeugen zum Bestimmen der Abdeckungsgrade.
f) FDA-Inspektionen
Bereiten Sie sich argumentativ auf die Frage eines FDA-Inspektors vor, warum Sie eine Testabdeckung unter 100 % erreicht haben. Folgende Argumente können Ihnen dabei dienlich sein:
- Eine Testabdeckung (z.B. eine Zweigabdeckung) von 100 % ist in der Regel nicht möglich.
- Sie sind der Empfehlung der FDA nach einem risikobasierten Ansatz gefolgt und haben kritische Methoden in der Tat mit dem geforderten Abdeckungsgrad getestet.
- Sie flankieren Ihre analytische Qualitätssicherung mit weiteren Maßnahmen wie Code Review und statischer Code-Analyse.
- An der steigenden Testabdeckung erkennt man, dass Sie kontinuierlich besser werden.
Tipp: Nutzen Sie die Coverage-Grade auch dazu, um die Wahrscheinlichkeit von Software-Fehlern abzuschätzen. Lesen Sie dazu hier mehr.
Schöner Artikel. Insbesondere der risikobasierte Ansatz erscheint mir als sehr sinnvoll und praktikabel.
Lieber Herr Johner,
sehr schöner Artikel.
Ich bin allerdings nicht sicher, ob die Anforderungen der FDA bzgl. Coverage richtig wiedergegeben sind:
„It [Decision Coverage] is considered to be a minimum level of coverage for most software products, but decision coverage alone is insufficient for high-integrity applications.“
In dem FDA Dokument „General Principles of Software Validation“ setzt die FDA „Decision Coverage“ mit „Branch Coverage“ gleich. Das was Sie mit „Decision Coverage“ bezeichnen, ist eigentlich die „Condition Coverage“. Somit wird laut FDA die oben beschriebene „Branch Coverage“ empfohlen.
Viele Grüße nach Konstanz,
Mark Hastenteufel
Sehr geehrter Herr Hastenteufel,
Sie haben Recht, die FDA definiert die Begriffe so. Leider gibt es bei der Decision Coverage verschiedene Definitionen/Sichtweisen. Weil hier aber die FDA entscheidend ist, folge ich gerne Ihrem Tipp und habe die beiden Überschriften angepasst.
Mit herzlichem Dank und vielen Grüßen, Christian Johner
Könnten Sie Zweigabdeckung nochmal anders erklären, oder genauer erklären – ich will das ja verstehen aber ich krieg den Zusammenhang zwischen Zeile 11 und 15 nicht.
Ist damit gemeint: falls debug mal false ist was nicht passiert, würde es keine konsolen ausgabe geben und dieser zweig wird nicht durchlaufen ?
LG
Genau so ist es: Die Bedingung in Zeile 11 wird nur mit „true“ abgeprüft. Daher ist diese Zeile gelb. Die Zeile 12 wird deshalb immer durchlaufen — damit mindestens einmal — weshalb sie in grün markiert ist.
In Zeile 11 ist nicht die mangelnde Anweisungsabdeckung, sondern die unvollständige Zweigabdeckung das Problem. Den else-Zweig sieht man allerdings nicht, daher wahrscheinlich die Frage.