Dynamische Verifikation: Unit- und Komponententests
Bei der dynamischen Verifikation wird die Software anhand definierter Testfälle ausgeführt und das tatsächliche Laufzeit-Verhalten gemessen. Dabei wird sichergestellt, dass Funktionen unter normalen Bedingungen, in Grenzfällen und in Fehlerzuständen korrekte Ergebnisse liefern, und es werden die Coverage-Daten erstellt, die gemäß ISO 26262, DO-178C, IEC 61508 und IEC 62304 als Verifikationsnachweis erforderlich sind.
Dieser Prozess beginnt mit den Unit-Tests. Jede Funktion, jedes Modul, jede Klasse und jede Komponente wird vor der Integration isoliert anhand ihrer Spezifikation verifiziert. Fehler, die in dieser Phase entdeckt werden, verursachen nur einen Bruchteil der Kosten im Vergleich zu Fehlern, die erst während der Integration oder im Feld entdeckt werden, und die hier erstellten Rückverfolgbarkeitsnachweise (Traceability) bilden die Grundlage für den Konformitätsnachweis.
Der Testablauf
Der dynamische Verifikations-Workflow in der sicherheitskritischen Entwicklung folgt einer festgelegten Abfolge. Vor Beginn der Tests werden die Anforderungen importiert und mit Testfällen verknüpft, wodurch die vom geltenden Standard geforderte Rückverfolgbarkeitsgrundlage (Traceability Baseline) geschaffen wird. Testumgebungen isolieren die zu testende Software mithilfe von Stubs und Mocks, um nicht verfügbare Abhängigkeiten zu ersetzen. Die Tests werden auf dem Host, dem Zielsystem oder beiden ausgeführt, wobei die Abdeckung durchgehend gemessen wird. Die Ergebnisse fließen zurück in das Anforderungsmanagementsystem und vervollständigen so die bidirektionale Dokumentation, die von den Auditoren überprüft wird.
Was bei Unit-Tests überprüft wird
Eine umfassende Unit-Test-Suite prüft mehr als nur die erwarteten Eingaben. Jeder Testfall wird auf der Grundlage einer spezifischen Anforderung erstellt und deckt Folgendes ab:
- Normale Eingaben und erwartete Ausgaben
- Randbedingungen und „Off-by-One“-Fälle
- Fehlerhafte Eingaben und ungültige Zustände
- Für die beteiligten Datentypen relevante Überlauf- und Unterlaufbedingungen
Verhalten, wenn Abhängigkeiten unerwartete Werte zurückgeben
In der sicherheitskritischen Entwicklung lässt sich jeder Testfall auf eine spezifische Anforderung zurückverfolgen, zu deren Verifizierung er konzipiert wurde. Die bidirektionale Rückverfolgbarkeit von der Anforderung über den Testfall bis zum Ergebnis ist gemäß DO-178C und ISO 26262 zwingend vorgeschrieben.
Rückverfolgbarkeit von Anforderungen
Das anforderungsbasierte Testen ist gemäß ISO 26262, DO-178C, IEC 61508 und IEC 62304 vorgeschrieben. Jeder Testfall muss auf eine spezifische Anforderung zurückverfolgt werden können, zu deren Verifikation er konzipiert wurde, und die Testergebnisse müssen bidirektional mit diesen Anforderungen verknüpft sein. Diese Aufzeichnung belegt, dass alle Anforderungen getestet wurden und dass kein Test ohne eine entsprechende Anforderung existiert.
Das „Requirements Gateway“ von VectorCAST verbindet sich mit externen Anforderungsdatenbasen, importiert Anforderungen in die Testumgebung und ermöglicht die direkte Verknüpfung von Testfällen mit diesen. Nach der Ausführung werden die Ergebnisse und Abdeckungsmetriken zurück in das Anforderungsmanagement-Tool exportiert. Anforderungen ohne Testabdeckung sind sofort erkennbar, ebenso wie Testfälle ohne verknüpfte Anforderung.
Aufbau der Testumgebung
Die zu testende Embedded Software hängt in der Regel von Hardware-Schnittstellen, Betriebssystemdiensten oder anderen Softwarekomponenten ab, die während der Komponententests nicht verfügbar sind oder deren Aufruf nicht praktikabel ist. Stubs ersetzen diese Abhängigkeiten und ermöglichen es, die zu testende Komponente isoliert zu testen, wobei die volle Kontrolle darüber besteht, welche Werte die einzelnen Abhängigkeiten zurückgeben.
VectorCAST generiert beim Aufbau einer Testumgebung automatisch Stubs für alle Abhängigkeiten. Stubs können pro Testfall aktiviert, deaktiviert oder so konfiguriert werden, dass sie spezielle Werte zurückgeben. Probe-Points erweitern diese Kontrolle noch weiter und ermöglichen es, an beliebigen Stellen in der zu testenden Unit Werte einzuspeisen, um Codepfade zu erreichen, deren Auslösung andernfalls spezielle Hardwarebedingungen oder Fehlerzustände erfordern würde. VectorCAST unterstützt zudem das Stubbing von Instanziierungen von Template-Funktionen, einschließlich expliziter und impliziter Instanziierungen von Membern von Template-Klassen, was für C++-Codebasen wichtig ist, in denen dieses Muster weit verbreitet ist.
Codeabdeckung
Die Code-Coverage-Messung misst, welcher Anteil des ausführbaren Codes durch die Testsuite ausgeführt wird. Sicherheitsstandards schreiben Mindestabdeckungsgrade vor, die sich nach der Kritikalität der zu entwickelnden Software richten.
- Die Statement-Coverage (Anweisungsabdeckung) stellt sicher, dass jede ausführbare Linie mindestens einmal ausgeführt wurde
- Die Branch-Coverage (Verzweigungsabdeckung) bestätigt, dass jeder Entscheidungspunkt jedes mögliche Ergebnis durchlaufen hat
- MC/DC (Modified Condition/Decision Coverage) belegt, dass jede Boolean-Bedingung in einer Entscheidung das Ergebnis unabhängig beeinflusst. Dies ist das strengste strukturelle Testkriterium und eine Anforderung für Software gemäß DO-178C DAL A und ISO 26262 ASIL D
VectorCAST misst alle diese Abdeckungstypen und beinhaltet „Industry Modes“, die automatisch die richtigen Abdeckungskriterien für einen bestimmten Standard und eine bestimmte Sicherheitsintegritätsstufe auswählen. Die Korrektheit der Abdeckungsergebnisse ist TÜV-zertifiziert.
Host- und Zielsystem-Test
Unit-Tests werden in der Regel zunächst auf dem Host-Rechner entwickelt und ausgeführt, um von hoher Geschwindigkeit und besserer Kontrolle zu profitieren. Schnelle Iterationszyklen, sofortiges Feedback und einfaches Debugging machen den Host zur idealen Umgebung für die Erstellung und Verfeinerung der Testsuite. Da beim Testen auf dem Host nicht der Ziel-Compiler zum Einsatz kommt, müssen compilerspezifische Verhaltensweisen separat auf der Zielhardware verifiziert werden.
VectorCAST ermöglicht es auf einfache Weise, dieselben Testfälle auf der Zielhardware auszuführen. Testumgebungen werden auf dem Host entwickelt und auf dem Zielsystem mithilfe von Runtime Support Packages (RSP) ausgeführt, die für viele Cross-Compiler und Echtzeitbetriebssysteme verfügbar sind. Die Messung der Testabdeckung, die Rückverfolgbarkeit und die Berichterstellung stehe in beiden Umgebungen gleichermaßen zur Verfügung.
Automatisierte Testgenerierung
Das manuelle Erstellen von Testfällen für eine umfangreiche Embedded-Codebasis ist zeitaufwendig und birgt die Gefahr von Lücken. Die automatisierte Testgenerierung (ATG) von VectorCAST generiert direkt aus dem Quellcode einen ersten Satz von Testfällen, wobei Grenzbedingungen und Codepfade im Fokus stehen, die bei der manuellen Erstellung häufig übersehen werden. Die Entwickler überprüfen und erweitern die generierten Tests, anstatt sie von Grund auf neu zu schreiben.
Teams, die es vorziehen, Testcode direkt zu schreiben, können „Coded Tests“ verwenden. Diese Funktion ermöglicht die Erstellung von Tests im xUnit-Stil unter Verwendung einer GoogleTest-kompatiblen Syntax, wobei der Zugriff auf die Funktionen von VectorCAST zur Code-Coverage-Messung, Rückverfolgbarkeit und CI/CD-Integration erhalten bleibt.
VectorCAST
VectorCAST ist die Plattform von Vector für dynamische Tests und Testautomatisierung von Embedded-Software in C-, C++- und Ada. Sie automatisiert den Aufbau der Testumgebung, generiert und verwaltet Testfälle, führt Tests auf Host- und Zielsystemen aus, misst die strukturelle Abdeckung und erstellt auditierbare Berichte.
Zu den wichtigsten Funktionen gehören: Einschließlich:
- Automatischer Aufbau der Testumgebung mit generierten Stubs, Mocks und Test-Harnesses
- Automatisierte Testgenerierung (ATG) zur Erstellung erster Testfälle direkt aus dem Quellcode
- Coded Tests für die Testerstellung im xUnit-Stil, kompatibel mit der GoogleTest-Syntax
- Requirements Gateway für bidirektionale Rückverfolgbarkeit zu externen Anforderungsdatenbasen
- Change-Based Testing, um nur die von Codeänderungen betroffenen Tests erneut auszuführen
- VectorCAST Test Explorer-Erweiterung für Visual Studio Code
- CI/CD-Integration einschließlich Jenkins, Azure DevOps und GitLab