Embedded-Softwareentwicklung

Mit Hyper-Coverage zur sicherheitszertifizierten Software

14. November 2022, 6:00 Uhr | Von Michael Wittner
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 1

Hyper-Coverage als Lösung

Eine Zusammenfassung der Coverage-Ergebnisse unterschiedlicher Varianten ist nur auf Zeilenbasis der ursprünglichen Quelldatei möglich. Aus der Analyse des Source-Codes jeder Variante kann ermittelt werden, welche Zeilen der ursprünglichen Quelldatei zu einem Statement/Branch oder zu einer Bedingung in dieser Variante gehören. Die Zeilen können daher wie folgt bewertet werden:

  • Wenn die Coverage-Ergebnisse einer Variante erfolgreich sind, dann können die dazugehörigen Zeilen der Quelldatei ebenfalls als erfolgreich markiert werden.
  • Falls mindestens eine Coverage-Art in einer Variante eine fehlende Abdeckung ergibt, dann wird die Zeile als nicht abgedeckt markiert.
  • Falls es in keiner Variante Coverage-Ergebnisse zu einer Zeile gibt, dann wird diese Zeile ebenfalls als nicht abgedeckt markiert.

Auf diese Art können nicht getestete Codezeilen einfach entdeckt werden. In Bild 4 ist das Ergebnis der Hyper-Coverage auf Source-Codeebene dargestellt.

passend zum Thema

Ergebnis einer zeilenweisen Bewertung des Source-Codes mit der Hyper-Coverage: Der gelb markierte Teil zeigt einen Codebereich, für den entweder keine Tests vorhanden sind oder die Tests nicht ausgeführt wurden.
Bild 4. Ergebnis einer zeilenweisen Bewertung des Source-Codes mit der Hyper-Coverage: Der gelb markierte Teil zeigt einen Codebereich, für den entweder keine Tests vorhanden sind oder die Tests nicht ausgeführt wurden. Die rot markierten Teile zeigen fehlende Coverage aus unterschiedlichen Coverage-Arten. Die Funktion »func3« wurde genügend getestet, sodass die geforderte Code-Coverage erreicht wurde.
© Razorcat Development

Der gelb markierte Teil zeigt einen Codebereich, für den entweder keine Tests vorhanden sind oder die Tests nicht ausgeführt wurden. Die rot markierten Teile zeigen fehlende Coverage aus unterschiedlichen Coverage-Testarten. Für die unten aufgelistete Funktion »func3« wurden genügend Tests durchgeführt, sodass die geforderte Code-Coverage erreicht wurde.

Der Vorteil der Hyper-Coverage besteht darin, dass zwar eine zeilenbasierte Auswertung vorgenommen wird, aber die zugrundeliegenden Coverage-Ergebnisse aus der gewählten Coverage-Art vollständig berücksichtigt werden. Wenn beispielsweise MC/DC-Coverage gefordert ist, dann muss für eine Zeile mit einer komplexen Bedingung in allen Varianten eine vollständige MC/DC-Coverage erreicht werden, damit die Zeile als erfolgreich bewertet gilt.

Regressionstests

Die Ergebnisse aus einer erweiterten Analyse der Quelldateien können neben der Nutzung der Coverage-Ergebnisse auch zur Optimierung des Regressionstests benutzt werden. Ein optimierter Regressionstest von Software spart Zeit und Ressourcen und ermöglicht kontinuierliches Testen im Entwicklungsprozess. Wichtig ist die korrekte Erfassung von Abhängigkeiten, sodass nur die relevanten, aber vor allem auch die unbedingt notwendigen Tests wiederholt werden.

Codeänderungen nur aufgrund von dateibasierten Prüfungen der Quell- und Header-Dateien zu erkennen, ist in der Regel zu grob, weil z. B. die Änderungen eines globalen Headers dazu führen würden, dass alle Tests wiederholt werden müssten.

Ändert sich der Wert des Präprozessor-Makros »PI« von einer Codeversion zur nächsten, dann ändert sich auch der präprozessierte Code der Funktion. Die Tests für diese Funktion müssen für die neue Codeversion also erneut durchgeführt werden
Bild 5. Ändert sich der Wert des Präprozessor-Makros »PI« von einer Codeversion zur nächsten, dann ändert sich auch der präprozessierte Code der Funktion. Die Tests für diese Funktion müssen für die neue Codeversion also erneut durchgeführt werden.
© Razorcat Development

Aufgrund der oben geschilderten Source-Codeanalyse stehen deutlich genauere Informationen zur Erkennung von Änderungen zur Verfügung. Jede einzelne Funktion oder Methode kann sowohl textuell in der präprozessierten Datei auf Änderungen geprüft als auch zusätzlich auf Änderungen im Funktions-Interface geprüft werden. Ein Beispiel ist in Bild 5 dargestellt, dort ändert sich der Wert des Präprozessor-Makros »PI« von einer Version der Software zur nächsten Version. Dadurch ändert sich der präprozessierte Code der Funktion, obwohl sich der Originalcode der Funktion nicht geändert hat. Die Tests für diese Funktion müssen also eindeutig erneut durchgeführt werden.

Wiederholen von Tests

Für die Ermittlung, welche Funktionen beim Regressionstest einer neuen Softwareversion erneut getestet werden müssen, sind folgende Prüfungen notwendig:

  • Im einfachsten Fall, wenn sich die Funktion im Original-Source-Code geändert hat, müssen die betreffenden Tests wiederholt werden.
  • Wenn sich die Funktion im präprozessierten Code geändert hat, ist ebenfalls ein erneuter Test notwendig.
  • Etwas komplizierter wird der Fall, wenn sich im präprozessierten Code einer Funktion nichts geändert hat, aber das Interface der Funktion durch Änderungen an verwendeten Elementen modifiziert wurde, z. B. Typänderung einer gelesenen Variable. Auch in diesem Fall ist ein erneuter Test notwendig.

Eine solchermaßen eingeschränkte Liste von erneut durchzuführenden Tests ist in einem Continuous-Integration-Prozess sinnvoll, um die Gesamtlaufzeit der Tests bei häufigen Testläufen möglichst klein zu halten, z. B. zur Verifikation von Codeänderungen vor dem Commit. Für ein neues Release einer Software wäre trotzdem eine Durchführung aller verfügbaren Tests anzuraten, da sich niemals ausschließen lässt, dass im Analyseprozess ggf. notwendige Regressionstests übersehen wurden.

Schneller zur gewünschten Codeabdeckung

Eine Zertifizierung sicherheitskritischer Software erfordert umfangreiche und normgerechte Tests aller Funktionen. Die Vollständigkeit der Tests wird unter anderem über die Code-Coverage nachgewiesen – bei Softwarevarianten auch für alle Codevarianten. Mit einer erweiterten Analyse der Quelldateien lassen sich wertvolle Informationen gewinnen, um nach kleineren Codeänderungen insgesamt weniger Tests erneut durchführen zu müssen. Auch die Erkennung von identischen Codeanteilen in Varianten ermöglicht ein Zusammenfassen von Coverage-Ergebnissen aus verschiedenen Tests und damit eine schnellere Erreichung der gewünschten Codeabdeckung. Die mehrfache Nutzung von Tests in Varianten mit jeweils erweiterten oder angepassten Testdaten verringert ebenfalls den Aufwand für die Testerstellung.

Die Ermittlung einer Hyper-Coverage aus den verfügbaren Coverage-Ergebnissen erlaubt eine vollständige Sicht der Testabdeckung auf Quelldateiebene, ohne die spezifischen Coverage-Anforderungen der Standards und Normen für die Entwicklung sicherheitskritischer Software zu verwässern. Im Gegenteil: Mit der Hyper-Coverage lassen sich zuverlässig nicht getestete Stellen in den originalen C/C++-Quelldateien erkennen.

 

Der Autor

Michael Wittner von Razorcat Development
Michael Wittner von Razorcat Development.
© Razorcat Development

Michael Wittner

ist Diplom-Informatiker und Geschäftsführer von Razorcat Development. Er arbeitet seit mehr als 25 Jahren im Bereich Softwareentwicklung und Test.

Nach dem Studium der Informatik an der TU Berlin entwickelte er als wissenschaftlicher Mitarbeiter bei Daimler Testmethoden und Testwerkzeuge. Seit 1997 ist er geschäftsführender Gesellschafter von Razorcat Development, dem Hersteller des Unit-Testtools TESSY und CTE sowie des Testmanagement-Tools ITE und der Testspezifikationssprache CCDL.


  1. Mit Hyper-Coverage zur sicherheitszertifizierten Software
  2. Hyper-Coverage als Lösung

Lesen Sie mehr zum Thema


Jetzt kostenfreie Newsletter bestellen!