VectorCAST für effiziente Unit- und Integrationstests in der Medizintechnik

In sicherheitskritischen Softwareprojekten steht die Qualität der Software an erster Stelle. Besonders bei Klasse-C-Software, die nach strengen Normen wie IEC 62304 (Medizintechnik) zertifiziert werden muss, ist es essenziell, dass jeder Aspekt der Software gründlich getestet wird. Fehler können in solchen Anwendungen nicht nur wirtschaftliche Verluste, sondern auch reale Gefahren für Menschenleben bedeuten.

Unit-Tests und Integrationstests sind in diesem Zusammenhang unverzichtbar. Sie stellen sicher, dass jede Funktionseinheit der Software korrekt arbeitet (Unit-Tests) und dass alle Komponenten im Zusammenspiel zuverlässig funktionieren (Integrationstests). In der Praxis erweisen sich diese Tests jedoch oft als zeit- und ressourcenaufwendig, besonders wenn die Testabdeckung maximiert werden soll.

Ein Lösungsansatz für diese Herausforderung bietet das Testwerkzeug VectorCAST. Es bietet eine Umgebung zur Automatisierung von Unit- und Integrationstests und hilft dabei, die Testabdeckung zu analysieren und sicherzustellen, dass keine kritischen Teile des Codes ungetestet bleiben.

In diesem Beitrag werden die Einsatzmöglichkeiten von VectorCAST für die Durchführung von Unit- und Integrationstests vorgestellt. Der Fokus liegt darauf, wie solche Tests effizient gestaltet und gleichzeitig die Testabdeckung und Qualitätssicherung auf einem hohen Niveau gehalten werden können. Abschließend wird ein praktisches Beispiel gezeigt, das die Anwendung von Testabdeckung und Probe Points in der Praxis verdeutlicht.
 

Was ist VectorCAST?

VectorCAST ist eine Testplattform, die speziell für die Automatisierung von Unit- und Integrationstests in sicherheitskritischen Softwareprojekten entwickelt wurde. Es unterstützt Entwicklerteams dabei, die Qualität und Zuverlässigkeit ihres Codes zu gewährleisten, indem es den gesamten Testprozess – von der Testfallerstellung bis hin zur Analyse der Testabdeckung – effizienter gestaltet.

Ein zentrales Merkmal von VectorCAST ist die Fähigkeit, Tests vollständig zu automatisieren und wiederholbar zu machen. Das Werkzeug integriert sich nahtlos in bestehende Entwicklungsumgebungen und erlaubt es, sowohl einzelne Code-Einheiten als auch ganze Module in verschiedenen Teststufen zu überprüfen. Diese Flexibilität ermöglicht es, Fehler frühzeitig zu erkennen und zu beheben, bevor sie in späteren Entwicklungsphasen aufwendiger werden.

Darüber hinaus bietet VectorCAST umfangreiche Testabdeckungsanalysen, die einen detaillierten Überblick darüber geben, welche Teile des Codes getestet wurden und welche Bereiche möglicherweise noch ungetestet sind. Mit der Funktion der Probe Points können gezielt bestimmte Stellen im Code beobachtet werden, um das Laufzeitverhalten besser zu verstehen und mögliche Fehlerquellen genauer zu identifizieren.

VectorCAST unterstützt verschiedene Programmiersprachen wie C, C++ und Ada und wird in vielen sicherheitskritischen Branchen, darunter die Automobilindustrie, Luftfahrt und Medizintechnik, eingesetzt.
 

Unit- und Integrationstests mit VectorCAST

VectorCAST unterstützt sowohl Unit-Tests als auch Integrationstests, um sicherzustellen, dass jede Funktionseinheit und deren Zusammenspiel im Gesamtsystem fehlerfrei funktioniert. Während Unit-Tests sich auf das Testen einzelner Funktionen oder Methoden innerhalb einer Klasse oder eines Moduls konzentrieren, dienen Integrationstests dazu, das Zusammenspiel mehrerer Module zu überprüfen und sicherzustellen, dass sie in Kombination korrekt funktionieren.

In diesem Beispiel richten wir eine Testumgebung für die Klasse MotorStatusHandler ein, die den Status eines Schrittmotors überwacht. Dazu wird die Klasse StepperMotorDriver verwendet, um Motordaten zu empfangen und diese im MotorStatusHandler weiterzuverarbeiten. Ziel der Unit-Tests ist es, sicherzustellen, dass die Methoden dieser Klassen erwartungsgemäß funktionieren, besonders in Bezug auf die Verarbeitung von Motordaten und die Fehlererkennung.

Zu testende Klasse (Header) in Vectorcast

Abbildung 1: Zu testende Klasse (Header)


Zu testende Klasse (Implementation) in Vectorcast

Abbildung 2: Zu testende Klasse (Implementation)

Fangen wir mit dem Setup an. In VectorCAST 2021 erstellen wir ein neues Projekt und geben den Compiler an, den wir verwenden möchten.

Anlegen eines Testprojekts in Vectorcast

Abbildung 3: Anlegen eines Testprojekts

Als nächstes erstellen wir eine Testumgebung.

Erstellung einer Testumgebung in Vectorcast

Abbildung 4: Erstellung einer Testumgebung

Bei der Erstellung der Testumgebung in VectorCAST ist Coverage-Typen als ‚Statement+MC/DC‘ (Statement Coverage und Modified Condition/Decision Coverage) zu wählen. MC/DC stellt sicher, dass jede Bedingung in einer Entscheidung und ihre Kombinationen mindestens einmal geprüft werden. Wir wählen auch die Option White-Box-Testing aus, da wir den internen Aufbau der Methoden kennen und gezielt auf verschiedene Zustände testen.

Build Options bei dem Einrichten der Testumgebung in Vectorcast

Abbildung 5: Build Options bei dem Einrichten der Testumgebung

Sobald die Testumgebung erstellt ist, stellt sie eine Liste der Klassenmethoden bereit, die getestet werden müssen.

Eine Testumgebung wird in Vectorcast aufgebaut

Abbildung 6: Testumgebung wird aufgebaut

Um ProcessStepperMotorData Methode mit Tests abzudecken, nutzen wir die automatische Generierung von Testfällen.

Zu testende Methode

Abbildung 7: Zu testende Methode


Automatische Generierung von Testfällen in Vectorcast

Abbildung 8: Automatische Generierung von Testfällen

Das Ergebnis sind drei Tests, die automatisch so generiert wurden, dass sie zusammen eine Methodenabdeckung gewährleisten. Es lohnt sich, diese Tests entsprechend umzubenennen, damit die Namen ihre Bedeutung vermitteln.

In der folgenden Abbildung sehen Sie einen automatisch generierten Testfall für die Methode ProcessStepperMotorData(), in dem wir das erwartete Verhalten konfigurieren und auch die Rückgabewerte im Abschnitt „Stub-Funktion“ ändern können.

Einrichten des Testfalls in Vectorcast

Abbildung 9: Einrichten des Testfalls

Nach der Ausführung des Tests öffnet sich ein Fenster mit der Testabdeckung für die getestete Methode, in dem die Codeabschnitte und logischen Bedingungen, die der Testfall abdeckt, grün angezeigt werden.

Testabdeckung nach der ersten Testdurchführung in Vectorcast

Abbildung 10: Testabdeckung nach der ersten Testdurchführung

Durch die Durchführung des nächsten Tests (Abbildung 11) erhalten wir zusätzliche Abdeckung (zu dem, was wir bereits haben).

Der Test Path in Vectorcast

Abbildung 11: Test Path

Zusätzliche Testabdeckung

Abbildung 12: Zusätzliche Testabdeckung

Dann richten wir den letzten Test ein und führen ihn aus, bis wir die vollständige Testabdeckung für die Methode erhalten.

Volle Testabdeckung der Methode in Vectorcast

Abbildung 13: Volle Testabdeckung der Methode


 

Verwendung von Probe Points in VectorCAST

Ein wesentlicher Aspekt beim Testen sicherheitskritischer Systeme ist das präzise Testen aller Verzweigungen und Bedingungen im Code. Besonders bei der Arbeit mit if-Statements und Abhängigkeiten von spezifischen Eingabewerten kann es vorkommen, dass bestimmte Pfade ohne zusätzliche Kontrolle nicht ausgeführt werden können. Genau hier kommen Probe Points ins Spiel.
Schauen wir uns ein Beispiel aus unserem Test für die Methode ProcessFaultDriverStatus() an (Abbildung 14). Dieser Code verarbeitet verschiedene Fehlerzustände des Motors und gibt Fehlermeldungen aus, wenn bestimmte Bedingungen erfüllt sind.

ProcessFaultDriverStatus Methode in Vectorcast

Abbildung 14: ProcessFaultDriverStatus Methode

Im folgenden Test Path, der durch VectorCAST erzeugt wurde, sehen wir, dass das erste if-Statement als TRUE ausgewertet wird, aber alle nachfolgenden Bedingungen FALSE bleiben:

Spezieller Test Path

Abbildung 15: Spezieller Test Path

Um sicherzustellen, dass dieser Testpfad durchlaufen wird, ohne dass eine der Bedingungen für die Fehlererkennung erfüllt wird, muss der Wert der Variablen motorDriverData entsprechend angepasst werden.

Durch das Platzieren eines Probe Points vor der Zeile if ((motorDriverData & MotorDriverDataMask::eTmc249aOt) != 0U), können wir den Wert von motorDriverData so ändern, dass die Bedingungen in den if-Anweisungen FALSE bleiben, was den Testpfad korrekt abdeckt. Auf diese Weise können wir sicherstellen, dass das erste if-Statement als TRUE und alle nachfolgenden als FALSE ausgewertet werden, ohne den ursprünglichen Code verändern zu müssen.

Die folgende Abbildung zeigt die Verwendung eines Probe Point, damit der Testfall den gezielten Testpfad abdeckt.

Platzieren eines Probe Point in Vectorcast

Abbildung 16: Platzieren eines Probe Point

Ohne die Verwendung von Probe Points könnte dieser Testfall nicht vollständig abgedeckt werden, da wir keinen direkten Einfluss auf den Wert von motorDriverData in der Laufzeit haben.

Probe Points erlauben es uns, gezielt in den Testprozess einzugreifen und Werte zu verändern oder zusätzliche Informationen zu sammeln, ohne den ursprünglichen Code zu verändern. Die Nutzung von Probe Points trägt erheblich dazu bei, dass sicherheitskritische Software gemäß den Normen vollständig getestet wird und somit eine hohe Zuverlässigkeit garantiert ist.
 

Best Practices beim Einsatz von VectorCAST

Um den Testprozess effizient zu gestalten und maximale Testabdeckung zu erreichen, sollten folgende Best Practices beachtet werden:

  1. Frühe Integration von Tests
    Tests sollten früh im Entwicklungszyklus integriert werden, um Fehler frühzeitig zu erkennen und teure Korrekturen in späteren Phasen zu vermeiden.
  2. Verwendung von Probe Points
    Probe Points helfen, schwer zugängliche Codepfade zu testen, indem sie Variablen während der Testausführung manipulieren und so sicherstellen, dass alle Bedingungen geprüft werden.
  3. Kombination von Coverage-Typen
    Die Kombination aus Statement Coverage und MC/DC (Modified Condition/Decision Coverage) gewährleistet eine lückenlose Abdeckung, insbesondere bei sicherheitskritischen Anwendungen.
  4. Verwendung von Stubs und UTT (Unit Test Targets)
    Stubs simulieren externe Abhängigkeiten, um den Fokus auf die Funktionseinheit zu legen. Es ist wichtig, je nach Bedarf zwischen Stubs und echten Implementierungen (UTT) zu wählen. Stubs werden genutzt, um externe Abhängigkeiten zu simulieren, während UTT verwendet wird, um den echten Code zu testen. Für externe Bibliotheken empfiehlt es sich Stubs zu verwenden, während UTT ideal ist, wenn die Funktionalität in der tatsächlichen Umgebung überprüft werden muss.
  5. Regelmäßige Wartung von Testumgebungen
    Testfälle und -umgebungen sollten regelmäßig aktualisiert werden, um sicherzustellen, dass sie stets den aktuellen Stand der Entwicklung widerspiegeln.

 

Fazit

VectorCAST ist ein vielseitiges und leistungsstarkes Werkzeug zur Durchführung von Unit- und Integrationstests in sicherheitskritischen Anwendungen wie zum Beispiel in der Medizintechnik. Es bietet umfangreiche Funktionen, um komplexe Testszenarien abzubilden und die Anforderungen an Testabdeckung zu erfüllen.
Durch den Einsatz von Probe Points, die flexible Nutzung von Stubs oder Unit Test Targets sowie die umfassende Unterstützung für verschiedene Coverage-Typen wie MC/DC oder Statement Coverage, können selbst komplexe und sicherheitskritische Systeme effizient getestet werden.

Kontaktieren Sie uns!

Autor

  • Volodymyr Skoryk verfügt über mehr als 10 Jahre Erfahrung in der Entwicklung von Embedded-Software für medizinische Geräte. Er war unter anderem an der Entwicklung von Software für Beatmungsgeräte und Patientenmonitoren maßgeblich beteiligt. Neben der Entwicklung von Anwendungssoftware hat Volodymyr auch umfassende Erfahrungen in der Hardwareentwicklung und dem Aufbau automatischer Steuerungssysteme gesammelt. Seine Leidenschaft liegt in der Programmierung von Hardwaresystemen, wobei er besonders die Möglichkeit schätzt, seine Arbeitsergebnisse unmittelbar zum Leben zu erwecken.

    Alle Beiträge ansehen Softwareentwickler
Auch interessant:

Cache auf einem Mikrocontroller – Was es zu beachten gibt

Wir haben vor kurzem für einen Kunden eine Firmwareerweiterung programmiert, welche der Anwendung ermöglicht Daten auf dem Mikrocontrollerflash zu speichern und zu lesen. Die Firmware läuft auf einem PIC32MZ, welcher mit einem Daten- und einem Instruktionscache ausgestattet ist. Wer schon mal versucht hat Software für einen PC mit Multi-Core CPU…