Code Coverage: Vollständigkeit von Software-Tests bestimmen

Donnerstag 22. September 2016

Code Coverage dient den meisten Software-Entwicklern als die wichtigste Metrik für die Vollständigkeit von Software-Tests.

Dieser Artikel verschafft Ihnen einen Überblick über die Abdeckungsgrade und gibt Tipps zum Bestimmen dieser.

1. Was Code Coverage ist

Code Coverage übersetzt man meist mit Abdeckungsgrad, Testabdeckung oder Code-Abdeckung. Diese Maßzahl gibt den Anteil der tatsächlich durchgeführten Tests zu 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 durchlaufenden 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

Code Coverage: Ein Beispiel

Abb. 1: Farbliche Markierung der beim Testen durchlaufenen Code-Abschnitte

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 / Condition 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.

Programmgraf zum Bestimmen des Code Coverage

Abb. 2: Programmgraf des in Abb. 1 gezeigten Codes

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% Zweigabdeckung bedingt eine 100% Anweisungsabdeckung. Das Umgekehrte gilt nicht. Damit ist die Zweigabdeckung das stärkere Maß als 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 4 atomare Teilbedingungen.

Die Zweigabdeckung unterscheidet nicht, aufgrund welche Teilbedingungen eine Bedingung als wahr oder falsch ausgewertet wird. Dies erreicht die Bedingungsabdeckung. Man unterscheidet dabei zwischen der Einfach- und der Mehrfachbedingungsabdeckung.

Einfachbedingungsabdeckung

Einfachbedingungsabdeckung gibt den Anteil der atomaren Teilbedingungen an, die mindestens einmal den Wert wahr und mindestens einmal den Wert falsch angenommen haben.

100% Einfachbedingungsabdeckung führt nicht zu 100% 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. D.h. 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.

2. Regulatorische Anforderungen an das Code Coverage

In vielen regulierten Branchen wie der Flugzeugindustrie oder Medizintechnik gibt es sogar normative Anforderungen. Sie finden diese am Beispiel der Medizintechnik hier vorgestellt:

a) Europa

Die IEC 62304 (Version 1.1) kennt den Begriff Code Coverage zumindest. 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“ 100% 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% 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“ sei, 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 des Code Coverage sollten Sie beachten:

  1. 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.
  2. Nicht vollständig testbar
    Ebenso widersetzen sich Teile des Codes wie sehr hardwarenahe Anweisungen dem Testen und damit dem Bestimmen der Code Coverage.
  3. 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.
  4. Aufwand
    Das Aufsetzen der Werkzeuge zum Bestimmen der Code Coverage bedeutet einen (einmaligen) Aufwand. Das Schreiben des Tests ebenso.
  5. 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.
  6. 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 dazu:

a) Integration im Entwicklungsprozess

Legen Sie in der entsprechenden Verfahrensanweisung, Arbeitsanweisung oder dem 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 müssen 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. maximalem 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 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 größer 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 ein fehlendes Hardware Abstraction Layer 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 an zu validierenden Werkzeugen 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 eine Frage eines FDA-Inspektors vor, dass Sie eine Test-Abdeckung von kleiner 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 werden kontinuierlich besser werden .
War dieser Artikel hilfreich? Bitte bewerten Sie:
1 Stern2 Sterne3 Sterne4 Sterne5 Sterne

Kategorien: Software & IEC 62304
Tags: ,

3 Kommentare über “Code Coverage: Vollständigkeit von Software-Tests bestimmen”

  1. Christian Wache schrieb:

    Schöner Artikel. Insbesondere der risikobasierte Ansatz erscheint mir als sehr sinnvoll und praktikabel.

  2. Mark Hastenteufel schrieb:

    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

  3. Prof. Dr. Christian Johner schrieb:

    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

Kommentar schreiben