Keine Angst vor Software-Varianten – Wiederverwendung und Vererbung von Testfällen
Die Herausforderung beim Testen von Software-Varianten besteht darin, dass jede Variante vollständig getestet werden muss. Über die Definition von Basistests, die an Variantentests vererbt werden, lässt sich redundante Arbeit leicht vermeiden. Bei jeder Änderung der Applikation muss der Entwickler die Tests nur an einer Stelle pflegen.
Anbieter zum Thema

Sicherheitskritische Normen der verschiedenen Industriezweige, z.B. die ISO 26262 für die Automobiltechnik oder die IEC 62304 für die Medizintechnik und übergreifend für alle Industriezweige die IEC 61511 verlangen beim Test eine vollständige Codeabdeckung (Code-Coverage). Das bedeutet, dass jede Software-Variante vollständig getestet werden muss. In der Praxis geschieht dies oft durch Kopieren der Tests einer Variante und der Anpassung der kopierten Tests an die jeweils andere Variante. Neue Anforderungen oder Änderungen der Software verteuern einen solchen Test der Varianten aufgrund redundant durchzuführender Änderungen in allen Varianten. Neben dem hohen Aufwand bei der Pflege und Erweiterung solcher Tests können sich z.B. durch Copy&Paste sehr leicht Fehler einschleichen, durch die letztendlich auch sicherheitskritische Fehler in der Applikation unentdeckt bleiben können.
Was ist eine Software-Variante?
Es gibt verschiedene Möglichkeiten, Software-Varianten zu erstellen (Beispiel C/C++ Source Code):
- Ein-/Ausschalten von Code-Teilen durch Defines
- Generierung von Code-Varianten über Tools (z.B. aus MATLAB)
- Kopieren, Umbenennen und Ändern von Quelldateien
- Gleiche Quellen auf verschiedenen Hardwareplattformen ausführen (bei hohen Sicherheitsanforderungen)
- Gleicher Code mit unterschiedlichen Applikationswerten
Eine Software-Variante ist durch eine bestimmte Konfiguration eines Software-Moduls (beispielsweise einer C Quelldatei) definiert. Diese Variante muss nicht notwendigerweise funktional sein, es kann sich auch um eine abstrakte Variante handeln, die in dieser Form niemals in einem fertigen Gerät seinen Dienst versehen wird. Erst durch spezifische Einstellungen (meist über Defines) werden aus einer abstrakten Basis-Variante die verschiedenen tatsächlich verwendbaren Software-Varianten.
Testziel: Code-Coverage
Für die vollständige Code-Abdeckung jeder Variante könnte das Messergebnis der Code-Coverage des variantenspezifischen Codes mit dem Messergebnis des gemeinsam genutzten Codes zusammengezählt werden. Das einfache Beispiel in Bild 1 soll verdeutlichen, warum ein solches Zusammenzählen von Code-Coverage nicht funktionieren kann und dabei Programmierfehler möglicherweise nicht erkannt werden. Die dargestellte Funktion hat in den Zeilen 19-23 einen gemeinsamen Teil und in den Zeilen 15-17 einen zusätzlichen Teil für Variante 1. Bei der Variante 1 wird vor der Prüfung der Variable „level“ ein weiterer Wert aufaddiert.
Der gemeinsame Teil in den Zeilen 19-23 könnte mit zwei Testfällen ausreichend getestet werden. Für die Variante 1 kommt kein zusätzlicher Programmzweig hinzu, so dass für eine vollständige Code-Coverage kein weiterer Testfall notwendig ist. Ein einfacher Testfall mit „supplementary_level > MINIMUM“ würde als funktionaler Test für die Variante ausreichen. Das Zusammenzählen der Coverage-Messergebnisse würde eine vollständige Codeabdeckung ergeben. Doch an dieser Stelle zeigt sich, dass ein einfacher Programmierfehler, wie das Fehlen des Additionsoperators in der Zeile 16 in Bild 2 dargestellt, nicht entdeckt werden würde.
Es reicht daher nicht, einzelne Teile eines mit Hilfe von Defines zusammengesetzten Varianten-Codes zu testen und die Messergebnisse der Code Coverage zusammenzuzählen: Jede Code-Variante ist wie ein eigenständiges Programm zu sehen, da ausgeblendete oder dazugekommene Teile die gemeinsamen Teile beeinflussen können.
Hoher Pflegeaufwand bei Änderungen
Es liegt in der Natur von Software-Varianten, dass sie ähnliche Funktionalitäten besitzen. Daher werden auch die notwendigen Tests relativ ähnlich sein. Es lohnt sich also, über Variantentests nachzudenken, gerade wenn die Unterschiede der Varianten relativ gering sind. Der Testaufwand lässt sich durch gezielte Wiederverwendung von Testfällen deutlich reduzieren.
Der einfachste Ansatz wäre, zunächst eine Menge von Basistests zu entwickeln, die mehr oder weniger für alle Varianten gelten. Diese Tests werden dann für jede Variante kopiert und nach Bedarf abgeändert. Man erspart sich dadurch die Neuerstellung von Tests, allerdings entsteht gleichzeitig eine Unmenge fast identischer Tests, die bei Änderungen der Software mit hohem Aufwand gepflegt werden müssen.
(ID:45622805)