Holen Sie sich die UMFANGREICHSTE Abdeckung für die Einhaltung von MISRA C! Erfahren Sie mehr >>

Das Problem mit der Pfadcode-Abdeckung

Von Parasoft

31. August 2011

3  min lesen

Warum unterstützen so wenige verfügbare Tools die Pfadabdeckung?

Hohe Anzahl von Pfaden

Die Anzahl möglicher Codepfade nimmt typischerweise exponentiell mit der zyklomatischen Komplexität eines Verfahrens zu. Das Erreichen eines hohen Prozentsatzes der Pfadabdeckung durch manuelles Schreiben von Testfällen ist für jede Methode, die mehr als nur eine Handvoll Zeilen enthält, effektiv unmöglich. Selbst automatisierte Tools zur Testgenerierung können Schwierigkeiten haben, Testfälle für eine vollständige Pfadabdeckung zu generieren, insbesondere wenn verschachtelte Schleifen beteiligt sind. Beispiel: Eine Methode mit einer Folge von 10 nicht verschachtelten if-Anweisungen verfügt bereits über 1024 (oder 210) mögliche Pfade. Der Codepfad für eine Schleife, die nach 499 Iterationen endet, unterscheidet sich vom Codepfad derselben Schleife, die nach 500 Iterationen endet. In ähnlicher Weise müssen eine Array-Speicheroperation, die aufgrund einer Nullreferenz eine Ausnahme auslöst, und dieselbe Operation, die eine ArrayStoreException auslöst, als unterschiedliche Codepfade behandelt werden.

Arten der Code-Abdeckung

Die Pfadabdeckung ist eine von vielen Arten von Codeabdeckungsmetriken. Im Folgenden finden Sie die Arten der Unterstützung der Abdeckung durch Parasoft-Testtools:

Grundblock Eine Folge von nicht verzweigten Anweisungen; Eine lineare Codesequenz ohne Verzweigungen der Kontrollflussroute.
Boolescher Ausdruck In C ++ ist ein boolescher Ausdruck einfach ein Ausdruck vom Typ 'bool'.

In C behandelt der C ++ - Test Folgendes als boolesche Ausdrücke:

  • Ein Vergleichsoperator (<, <=, ==,>,> = ,! =) Mit nicht booleschen Argumenten.
  • Jedes Argument des booleschen Operators (||, && ,!).
  • Bedingung in Anweisungen für if, for, while und do-while.
  • Zustand in? Operator.
Bedingung Ein atomarer boolescher nicht konstanter Ausdruck, der Teil der MC / DC-Entscheidung ist.

Ein Unterausdruck der MC / DC-Entscheidung wird als Bedingung angesehen, wenn er keine booleschen Operatoren enthält (&&, || ,!).

Wenn ein gegebener atomarer Ausdruck in einer Entscheidung mehr als einmal vorkommt, ist jedes Auftreten eine bestimmte Bedingung.

Entscheidung / Zweig Entscheidung / Verzweigung ist die mögliche Kontrollflussentscheidung, die am Verzweigungspunkt im Code getroffen werden muss. Der C ++ - Test berücksichtigt if-else, for, while, do-while und switch-Anweisungen als Verzweigungspunkte. Der C ++ - Test berücksichtigt keine dynamischen Verzweigungspunkte wie Ausnahmebehandlungsroutinen (Throw-Catch-Anweisungen).
 MC / DC-Entscheidung Ein boolescher Ausdruck der obersten Ebene, der aus Bedingungen und null oder mehr booleschen Operatoren besteht. Der C ++ - Test berechnet MC / DC und SCC für alle booleschen nicht konstanten Ausdrücke im Quellcode mit Ausnahme der Konstruktorinitialisierer und Funktionsstandardargumente.
Weg Eine eindeutige Folge von Basisblöcken vom Funktionseingang bis zum Austrittspunkt.

Schwierigkeiten beim Erkennen und Abdecken von Pfaden

Automatisierte Testgenerierungswerkzeuge für die Pfadabdeckung müssen zuerst bestimmen, welche Codepfade möglich sind und welche nicht, und dann in der Lage sein, Testeingaben zu generieren, die alle möglichen Pfade abdecken. Beide Schritte sind sehr zeitintensiv und die Genauigkeit der Ergebnisse kann nicht wirklich garantiert werden, da die erforderliche Analyse Probleme beinhaltet, von denen bekannt ist, dass sie NP-hart oder sogar unentscheidbar sind (wie das berüchtigte Stoppproblem).

Repräsentationsherausforderungen

Im Gegensatz zur Anweisungs- und Zweigabdeckung ist die Pfadabdeckung schwer zu visualisieren. Das Markieren von Linien oder Ausdrücken mit unterschiedlichen Farben reicht nicht aus, um diese Art von Abdeckungsinformationen zu übermitteln. Aufgrund des Fehlens einer leicht verständlichen Visualisierung bleibt die Pfadabdeckung für viele Entwickler ein schwieriges Konzept.

Die praktischen Ansätze zum Erreichen der Pfadabdeckung sind für die automatisierte und manuelle Testgenerierung ähnlich. Anstatt zu versuchen, alle möglichen Codepfade zu finden, ist es hilfreich, sich auf „interessante“ Codepfade zu konzentrieren. Es ist wenig sinnvoll, einen Testfall zu schreiben, der eine Schleife 499 Mal ausführt, und dann einen weiteren Testfall hinzuzufügen, der die Schleife 500 Mal ausführt, wenn nichts wirklich anderes passiert.

Anstatt einen Top-Down-Ansatz zu verwenden, ist es häufig sinnvoller, einen Bottom-Up-Ansatz zu verwenden, der an möglichen Fehlerpunkten beginnt und dann Codepfade findet, die zu den Fehlern führen würden. Zu den potenziellen Unruhestiftern zählen nicht nur mögliche Nullreferenzen (NullPointerException), Typinkompatibilitäten (ClassCastException, ArrayStoreException), Verstöße gegen Arraygrenzen (ArrayIndexOutOfBoundsException), sondern auch Division durch Null (ArithmeticException) oder potenzielle Synchronisationsprobleme (IllegalMonitorStateException). Der schwierige Teil ist, dass diese Ausnahmen als Nebeneffekt von Bytecode-Anweisungen auf niedriger Ebene auftreten und nirgendwo deklariert werden. Testtools, die eine Flussanalyse des getesteten Codes durchführen können, können sehr hilfreich sein, um Codepfade zu identifizieren, die weiter getestet werden müssen.

Klasse Listing4 {public static int add (int a, int b) {return a + b; }} öffentliche Klasse Listing4Test erweitert junit.framework.TestCase {public void testAdd0 () {int result = Listing4.add (0, 0); assertEquals (0, Ergebnis); }}

Auflistung 4: Eine Methode mit nur einem Codepfad und dem entsprechenden JUnit-Test

 

Klasse Listing4 // Listing 5, tatsächlich {public static int add (int a, int b) {return 0; }}

Auflistung 5: Eine stark vereinfachte Implementierung, die den Test noch bestehen würde

***

Bildquelle: Brightsea

Von Parasoft

Die branchenführenden automatisierten Softwaretest-Tools von Parasoft unterstützen den gesamten Softwareentwicklungsprozess, vom Schreiben der ersten Codezeile über Unit- und Funktionstests bis hin zu Leistungs- und Sicherheitstests, wobei simulierte Testumgebungen genutzt werden.

Erhalten Sie die neuesten Nachrichten und Ressourcen zum Testen von Software sofort.