Unter Unit-Testing wird in der Software-Entwicklung das Testen von Software-Units verstanden. Allerdings gibt es kein einheitliches Verständnis darüber,
- was eine Software-Unit ist,
- was einen guten Unit-Test auszeichnet und
- welche regulatorischen/gesetzlichen Anforderungen erfüllt werden müssen.
Dieser Artikel verschafft Klarheit.
1. Testobjekte: Was beim Unit-Testing getestet wird
a) Übliches Verständnis von Software-Units
Beim Unit-Testing werden abgegrenzte Teile eines Software-Systems getestet. Je nach Größe dieser Teile bezeichnet man diese Unit-Tests auch als
- Komponententests,
- Modultests oder
- Klassentests.
Je nach Bezeichnung entsprechen die Units also Komponenten, Modulen oder Klassen.
Unabhängig von ihrer Art bzw. Größe müssen diese „Units“ Schnittstellen anbieten, beispielsweise:
- Methoden einer Java-Klasse
- REST-API eines Micro-Services
- API einer C++-Bibliothek
- Java-Script-API eines Webassemblys
b) Besonderes Verständnis der IEC 62304 von Unit-Tests
Für die Entwicklung von Medizinprodukten und IVD ist die Norm IEC 62304 relevant. Auch sie kennt Software-Einheiten, auf Englisch Software Units. Diese Software-Einheiten definiert sie als:
„Software-Komponente, die nicht in weitere Komponenten unterteilt ist“.
Damit hängt die Granularität der Software-Units von der Zerlegung des Software-Systems in der Software-Architektur ab (s. Abb. 1).
In Abb. 1 sind die Software-Units (im Sinne der Norm) die rot markierten Komponenten. Hingegen verstehen Entwicklerinnen und Entwickler unter Units (beim Unit Testing) meist die Komponenten auf der untersten Ebene (in weiß dargestellt).
2. Testzeitpunkt: Wann das Unit-Testing erfolgt
Hersteller sollten die Unit-Tests während oder spätestens unmittelbar nach der Entwicklung jeder einzelnen Software-Unit implementieren und durchführen. Erst wenn die einzelnen Software-Units erfolgreich getestet wurden, werden diese stückweise integriert und dabei Integrationstests unterzogen (s. Abb. 2).
Erst zum Schluss wird das komplette Software-System getestet (z. B. Lasttests unterzogen), bevor anschließend die Validierung erfolgt (z. B. die Usability-Tests).
Lesen Sie hier mehr über das Software-Testing und die verschiedenen Definitionen des Begriffs Software-Validierung.
3. Testziele: Was das Unit-Testing prüfen kann
Das Unit-Testing soll einen Beitrag zu „guter Software“ leisten. Die ISO 25010 nennt die Software-Qualitätseigenschaften (Qualitätsziele).
Qualitätsziele gemäß ISO 25010 | Beitrag der Unit-Tests zum Erreichen des Qualitätsziels |
Funktionalität | Unit-Tests können die funktionale Korrektheit prüfen (z. B. ob eine Formel das richtige Ergebnis berechnet). Ob eine Software die funktionalen Anforderungen abdeckt, findet man über Unit-Tests nur dann heraus, wenn diese Funktionen definiert und implementiert wurden. |
Robustheit | Unit-Tests können überprüfen, ob Software-Units stabil gegen Fehleingaben sind. |
Gebrauchstauglichkeit | Die Gebrauchstauglichkeit ist beim Unit-Testing meist kein Testziel. |
IT-Sicherheit | Unit-Tests können ausgewählte Aspekte der IT-Sicherheit prüfen, etwa die korrekte Ver- und Entschlüsselung von Inhalten. |
Performanz | Unit-Tests sollten Performanz-Probleme (wie lange Berechnungsdauern, hoher Ressourcen-Verbrauch) bereits auf Ebene der Software-Units identifizieren. Denn diese Probleme sind in umfangreichen Software-Systemen schwerer zu verorten. |
Wartbarkeit | Bereits die Tatsache, dass sich die Komponenten (Software-Units) einzeln und unabhängig bei Unit-Tests testen lassen, spricht für die schwache Kopplung der Komponenten und damit für die Wartbarkeit des Software-Systems. |
Portierbarkeit | Meist überprüfen die Unit-Tests nicht die Portierbarkeit. Diese Übertragbarkeit auf andere Laufzeitumgebungen aus Hard- und Software prüfen die Hersteller vornehmlich mit dem ganzen Software-System. |
Interoperabilität | Die Interoperabilität bezieht sich auf das Zusammenspiel von zwei oder mehr Software-Systemen oder Komponenten. Daher ist die Interoperabilität meist das Testziel von Integrations- und Systemtests |
4. Testmethoden: Was gute Unit-Tests auszeichnet
Ein gutes Unit-Testing zeichnet sich dadurch aus, dass
- die Fehler (sprich Abweichungen von den Qualitätszielen) möglichst vollständig gefunden werden,
- diese Fehler möglichst früh gefunden werden und
- der Aufwand für das Testen möglichst gering ist.
Eine gute Testmethodik hilft, diese Ziele zu erreichen (s. Tabelle 2).
Ziel | Methoden zur Zielerreichung (Beispiele) |
Fehler vollständig finden | Die Entwicklerinnen und Entwickler sollten die Testfälle systematisch ableiten. Dafür stehen Blackbox-Testmethoden wie das äquivalenzklassen- und grenzwertbasierte Testen zur Verfügung. Zusätzlich sollte das Entwicklungsteam beim Festlegen der Testfälle die Kenntnis des Source-Codes nutzen. Dazu zählt auch, dass sie ein Mindestniveau für die Code-Coverage bestimmen und erreichen. |
Fehler möglichst früh finden | Fehler finden sich besonders früh, wenn die Unit-Tests parallel mit dem zu prüfenden Code geschrieben werden. Daraus folgt die Regel, dass für jede Software-Unit (bzw. Software-Modul oder Software-Komponenten) zwingend immer die zugehörigen Unit-Tests entwickelt werden. Die automatisierte und regelmäßige Ausführung von Unit-Tests als Regressionstests macht es möglich, Fehler, die durch die Änderung des Codes eingeführt werden, schnellstmöglich zu finden und zu beseitigen. |
Aufwand für das Testen minimieren | Es gibt Software-Werkzeuge, welche nicht nur Skeletons von Testmethoden, sondern sogar Implementierungen von Unit-Tests generieren. Bei der modellbasierten Entwicklung (z. B. mit Domain Specific Languages) kann diese automatische Generierung besonders weit getrieben werden. Die Automatisierung erspart das wiederholte manuelle Anstoßen der Unit-Tests und das Schreiben der Fehlerprotokolle. |
5. Regulatorische Anforderungen an das Unit-Testing
a) Anforderungen der IEC 62304
Die IEC 62304 kennt kein „Unit Testing“. Sie erwartet eine Prüfung, ob die Software-Einheiten (auf Englisch Software Units) vorher festgelegte Akzeptanzkriterien erfüllen.
Abhängig von der Sicherheitsklasse (hier mehr dazu)
- können Hersteller auf diese Verifizierung verzichten (Klasse A) oder
- die Akzeptanzkriterien so bestimmen, dass sich diese nur mit einer Analyse des Quellcodes (z. B. Code Review, statische Code-Analyse) überprüfen lassen (Klasse B),
- oder sie müssen tatsächlich die Software-Einheit testen, d. h. ein Unit-Testing durchführen.
In jedem Fall sind die Hersteller verpflichtet, diese Prüfungen zu planen, zu spezifizieren und zu dokumentieren.
Viele Hersteller verstehen unter dem Unit-Testing das Testen von Methoden oder Funktionen und gehen (bei OO-Entwicklungen) hinunter bis auf die einzelnen Klassen (weiße Kästchen in Abb. 1). Im Architekturdokument sind als kleinste Komponenten aber nur die gröber granularen Teile der Software erkennbar (rote Kästchen in Abb. 1) — genau das sind die Software-Einheiten im Sinne der Norm.
Mit anderen Worten: Die Software-Entwickler testen sehr feingranular (und nennen das Unit Testing). Sie testen aber nicht die in der Software-Architektur spezifizierten Software-Einheiten. Und das ist ein Verstoß gegen die IEC 62304.
b) Anforderungen der FDA an Unit-Tests
Die FDA formuliert ihre Vorstellungen vom Unit Testing in den Guidance-Dokumenten, z. B. in der Software Validation Guidance. Sie nennt diese Tests „Tests for Modules and Functions“, die sich auf der einen Seite in den Source Code und auf der anderen zurück zur Architektur verfolgen lassen müssen.
Ähnlich vage formuliert die FDA im Guidance-Dokument Content of the Premarket Submissions for Software contained in Medical Devices die Anforderungen an die „Verification and Validation“.
Umso überraschender ist angesichts dieser unpräzisen Vorgaben, dass 100 % Zweigabdeckung „is considered to be a minimum level of coverage for most software products, but decision coverage alone is insufficient for high-integrity applications“. Diese Forderung haben die Software-Experts des Johner Instituts noch bei keiner Firma als erfüllt vorgefunden.
6. Tipps zum Unit Testing
Tipp 1: Wählen Sie die richtige Granularität
Vermeiden Sie die oben erwähnte typische Falle, dass Sie zahllose Unit-Tests durchführen, aber die Software-Einheiten nicht explizit testen. Voraussetzung ist, dass Sie isoliert testbare Software-Einheiten haben. Dies ist eine Frage der Güte Ihrer Architektur.
Ergänzen Sie also Ihre Unit-Tests (gemäß Ihrer Definition) durch die Tests der wahrscheinlich gröber granularer Software-Einheiten.
Tipp 2: Nutzen Sie schlimmstenfalls Akzeptanzkriterien statt Unit-Testing
Wenn Sie aus Zeitgründen oder wegen einer verkorksten Software-Architektur Ihre Software-Einheiten nicht (automatisiert) testen können, dann legen Sie bei Software-Einheiten der Klasse A und B zumindest formale Akzeptanzkriterien fest, z. B. Kodierrichtlinien, Metriken oder Namenskonventionen. Das hat zwar wenig mit professionellem Software-Engineering zu tun, erfüllt aber die wenigen Anforderungen der IEC 62304. Bei Software der Klasse C bleibt Ihnen dieser Kunstgriff verwehrt.
Bei Klasse C müssen Sie als Teil der Akzeptanzkriterien (soweit anwendbar) auch Performanz-Aspekte, Fehlerbehandlung, Speicherauslastung usw. prüfen. Generell sollten die Akzeptanzkriterien von Unit-Tests die in der Software-Architektur spezifizierten Anforderungen sein.
Tipp 3: Setzen Sie Werkzeuge für das Testing ein
Automatisieren Sie auch diese Tests, um sie als Regressionstests (idealerweise täglich) wiederholen zu können.
Das setzt voraus, dass Sie Unit-Testwerkzeuge (wie JUnit, NUnit oder CppUnit) ebenso im Einsatz haben wie Werkzeuge für die kontinuierliche Integration (wie sie Kombinationen von ANT, make, Maven oder Grunt im Zusammenspiel mit Continous Integrationstools wie Jenkins/Hudson erlauben).
Für die statische Code-Analyse (z. B. die Analyse der Code-Metriken) gibt es ebenfalls zahlreiche Werkzeuge, ebenso für das Bestimmen des Code-Coverage.
Für die Verwaltung des Unit-Test-Codes und der Testergebnisse sind Versionsverwaltungssysteme wie git hilfreich.
Die ISO 13485 fordert die Validierung der Werkzeuge! Lesen Sie hier mehr zur Validierung von Werkzeugen.
Werkzeuge können nicht immer bewerten, ob der Test erfolgreich war. Beispielsweise bestimmt ein Tool den Statement-Coverage-Grad mit 62 %. Doch ist damit das Akzeptanzkriterium erfüllt? Genau diese Bewertung verlangt die IEC 62304.
7. Fazit, Zusammenfassung
Die Anforderungen der IEC 62304 an das Unit-Testing sind überschaubar und liegen eher unterhalb dessen, was man als Stand der Technik bezeichnet.
Unit-Tests sind die „Versicherung“ für jeden Software-Hersteller. Dank vieler Werkzeuge sind sie schnell implementiert und ausgeführt. Das methodische Wissen, wie man Unit-Tests schreibt, ersetzen sie aber nicht.
Das Team des Johner Instituts unterstützt Hersteller von IVD und Medizinprodukten beim Unit-Testing:
- Der Auditgarant stellt zahlreiche Templates zur Verfügung, z. B. einen IEC 62304-konformen Entwicklungsplan. Dieser wiederum fordert die Unit-Tests.
- Zahlreiche Videos im Auditgarant sowie der Johner Academy erläutern die Anforderungen der IEC 62304 und geben konkrete Tipps, um diese Anforderungen schnell und einfach zu erfüllen.
- Das Beratungsteam hilft bei der Prüfung von Entwicklungsplänen und beurteilt auf Wunsch die komplette Software-Akte. So gelingt eine schnelle Zulassung der Produkte.
- Mit Penetrationstests decken die IT-Security-Experts des Johner Instituts (bisher) immer Schwachstellen auf. So lassen sich diese beseitigen, bevor sie in der Praxis zu Problemen führen.
- Im Micro-Consulting beantworten die Software-Experts Antworten Ihre Fragen. Nicht nur zum Unit-Testing.
Änderungshistorie
- 2024-08-14: Artikel komplett neu geschrieben
- 2016-11-16: Erste überarbeitete Version des Artikels veröffentlicht
Die FDA fordert ja die Möglichkeit einer unabhängigen Bestätigung des Resultats “ factual records documenting the result of an examination, which support the pass/fail conclusion in an unambiguous and understandable manner, and which allow for independent confirmation of the result“
Heisst das nicht auch, dass man in der Lage sein muss, zu zeigen was der Test gemacht hat. Bei manuellen Tests ist das ja einfach, indem man die Test Schritte und Resultate auf Papier bringt (PDF). Wie kann man dasselbe für Automatisierte tests erreichen?
Für mich ist die Dokumentation eines automatisierten Tests der Test Code selbst, entsprechend würde ich den Source Code archivieren so dass ich jederzeit darauf zugreifen und zeigen kann was der Test gemacht hat.
Wie sehen Sie dass?
Absolut, das sollte man zeigen können. Bei automatisierten Tests sind die Schritte einschließlich der pass/fail-Krititerien im Source-Code. Das sehe ich genau wie Sie. Daher sollte der Test-Code unbedingt der gleichen Dokumentenlenkung unterworfen sein wie der Programm-Code und die Testergebnisse.
Sie weisen darauf hin, dass es aus aus normativer Sicht nicht ausreichend ist nur Unit-Tests (aus Entwickler-Sicht, weisse Kästchen) durchzuführen, sondern dass die Software-Einheiten (Units im normativen Sinne, rote Kästchen) explizit getestet werden müssen.
Im folgenden Artikel gehen Sie jedoch nicht weiter darauf ein, wie mit den „Entwickler-Tests“ zu verfahren ist. Ich stelle mir daher folgende Frage:
Einige Entwickler-Tests entstehen klar Bottom-Up, ergeben sich also aus der Art und Weise wie eine Funktionalität umgesetzt wurde, also aus dem Aufbau der weissen Kästchen. Is es ausreichend, wenn die „Anforderungen“ an diese Tests nur implizit innerhalb der (automatisierten) Tests beschrieben sind? D.h., dass hierzu keine getraceten Requirements vorhanden sind? So lassen sich wirkliche Requirements an die Software, also solche bis auf Ebene der normativen Units, von „Erwartungshaltungen“ der Entwickler trennen.
Lassen sich solche „Entwickler-Tests“ für die Code-Coverage heranziehen?
Sehr geehrter Herr Klöckner,
danke für die wichtige Frage!
Ich würde Sie sehr ermutigen, die „Entwicklertests“ weiter durchzuführen. Die Anforderungen, die Sie damit abtesten sind im Testcode enthalten. D.h. Sie müssen keine Requirements für jedes weiße Kästchen formulieren.
Meine Aussage war vielmehr, dass Sie auch und aus regulatorischer Sicht v.a. die roten Kästchen testen.
Sie dürfen durchaus den Code-Coverage der Entwickler-Tests heranziehen. Das würde ich auch empfehlen, weil dieser Coverage-Grad i.d.R. auch viel höher und aussagekräftiger ist.
Viele Grüße, Christian Johner
Vielen Dank für die sehr hilfreichen Informationen. In unserem SW Entwicklungsprozess verwenden wir die Software Requirement Specification für die Anfordeurngen an das SW System. Die Software Design Specification bildet das Design und das detaillierte Design wieder. Im Augenblick brechen wir die Anforderungen auf SRS Ebene (Ebene 0 – SW System-Ebene) auf Ebene 1 (Software Design Ebene – Wir nennen die Items auf dieser Ebene Komponenten) runter, und die Anforderungen brechen wir weiter runter auf Ebene 2 (Software detailled design – Hier sind unsere 62304 UNITs).
Auf diese Weise bekommen wir auch die Akzeptanzkriterien für unsere UNITs. Das heißt, wir definieren auf jeder Ebene unsere Software Architektur formale Anforderungen die auch formal geprüft werden, samt Test-Spezifikation, Testprotokoll und Traceability-Matrix.
Inzwischen bin ich aber der Meinung, dass die 62304 dieses runterbrechen von Anforderungen gar nicht verlangt, sondern lediglich das Runterbrechen (Dekomposition ) der Architektur und eine Architektur-Traceability.
Jetzt möchte ich gerne die Anfroderungen aus unserem SDS komplett entfernen, so dass es endlich ein reines Design-Output Dokument wird und nicht selbst wieder neue Anforderungen definiert und die Akzeptanzkriterien auf andere Art und Weise definieren (Generell: Code-Reviews, static code analysis, Entwickler-Unit-Tests + Funktional: Prüfen der Anwendbarkeit der Anforderungen die in der 62304 5.5.4 angegeben sind).
Jetzt bin ich aber ins Zweifeln gekommen, ob das richtig ist was ich vor habe, weil ich in diesem Artikel gelesen habe: „Generell sollten die Akzeptanzkritieren von Unit-Tests die in der Software-Architektur spezifizierten Anforderungen sein“
Jetzt war ich eigentlich sicher, dass in die Software Architektur keine Anforderungen rein gehören, damit es ein klares Design-Output Dokument ist. Könnten sie zu dem Punkt ein paar Worte sagen: Software Architektur – Anforderungen ja oder nein?
Danke im voraus,
Beste Grüße,
Ty-4
Sehr geehrter Herr Ty-4,
danke für Ihre ausführliche Schilderung!
Eine Software-Architektur ist (u.a.) die Zerlegung eines Software-Systems in Komponenten und eine Spezifikation der Schnittstellen dazwischen.
Jede Spezifikation einer Schnittstelle (einer Komponente) ist eine Beschreibung, wie sich die Software-Komponente über diese Schnittstelle verhalten soll. Und diese Beschreibung entspricht Anforderungen — allerdings an eine Komponente und nicht mehr an das Software-System insgesamt.
Bei den Komponententests (z.B. Unit-Tests) prüfen Sie, ob sich die Software gemäß dieser Spezifikationen verhält. D.h. Sie testen ob die Komponente die Komponentenanforderungen erfüllt.
Damit setzt eine Software-Architektur die Software-Anforderungen d.h. die Anforderungen an ein Software-System in eine Aufteilung des Systems in Komponenten und in eine Anforderungen an diese Komponenten um.
Hilft das ein wenig? Falls nicht, haken Sie gerne nach.
Viele Grüße, Christian Johner
Vielen Dank für die schnelle Antwort!
Ja, sie hilft auf jeden Fall schon mal weiter. Demnach ist die Antwort auf die Frage: Ja, in der SW Architektur werden Anforderungen definiert, die von den Software System Anforderungen abgeleitet werden.
Allerdings widerspricht das der Trennung zwischen Design Input und Design Output. Wenn mich heute jemand fragt was unser SDS eigentlich in dem Sinne ist, muss ich antworten: „Beides, es ist der Design-Output für das Software System (SRS) und der Design-Input für unser Source-Code. Würden sie das auch so interpretieren?
Wenn ich im Web z.B. nach Templates für die 62304 suche, ist es immer so, dass im SRS-Template Beispiele für Anforderungen drin stehen. Im zugehörigen SDS allerdings werden an der Stelle wo Komponenten oder UNITS definiert werden nur die Anforderungen aus dem SRS erwähnt, die von der Komponente oder UNIT erfüllt werden. Es tauchen keine neuen Anforderungen auf. Gerne kann ich ihnen per E-Mail mal solche Templates schicken, und die Stellen die meine markieren?
Sehr geehrter Herr Ty-4,
sowohl die SW-Architektur als auch die darin identifizierten Anforderungen an die Komponenten sind Design-Output. Damit gibt es keinen Widerspruch.
Die Trennung von Design-Input und Design-Output bezüglich der Anforderungen bestenfalls auf Ebene des Produkts, aber nicht auf Ebene der Komponenten.
Wenn es keine Komponenten-Anforderungen gäbe, könnten Sie keine Unit-Tests entwickeln. Denn diese müssen genau diese Anforderungen abprüfen.
Diese Ableitung von Produkt-Anforderungen aus Stakeholder-Anforderungen, von Komponenten- (z.B. PESS) Anforderungen aus Produkt-(z.B. PEMS) Anforderungen, von Software-Anforderungen aus PESS-Anforderungen, von Unit-Anforderungen aus Software-Anforderungen muss im „vertikalen Tracing“ erkennbar sein. Beispielsweise die IEC 60601-1 beschreibt das sogar explizit z.B. in Bild H2.
Beste Grüße, Christian Johner
Alles klar. Dann werde ich meine Bemühungen an der Stelle die Anforderungen aus dem SDS zu nehmen und einen anderen Weg für die Akzeptanzkriterien zu finden erst mal einstellen. Vielen Dank wie immer für die schnellen Rückmeldungen.
Hallo Herr Johner,
ich habe gerade mit sehr großem Interesse diesen spannenden Dialog gelesen, da ich an einer verwandten Fragestellung feststecke und etwas den Verdacht habe, dass ich ein paar Aspekte bisher falsch interpretiert haben könnte:
1. Auch ich war bisher der Annahme, dass es sich bei den Anforderungen (unabhängig, ob sie gegen das (SW) System auf oberstem Level oder – auf tieferem Level – gegen eine SW Unit formuliert sind, um Design Input im Sinne der FDA handelt. Das würde aus meiner Sicht zu einer Art rekursivem Zick-Zack-Pattern führen, bei dem z.B. „System Design“ als Design Output auf dem System Level zu Design Input für die Sub-Systeme auf der nächst tieferen Systemhierarchieebene (z.B. für SW Items oder Units) wird. Auf der unteren Hierarchieebene würde dann wiederum Design Output „als Antwort“ auf diesen Design Input entstehen.
2. Da die FDA grundsätzlich eine formale Traceability von Design Input zu Design Output und zur Verifikation fordert, bin ich davon ausgegangen, das sich auch diese Forderung auch „entlang der (SW-)Systemdekomposition“ bis auf die kleinste Zerlegungsebene fortsetzt. Was bedeuten würde, dass alle Dokumentationselemente von Design Input über Design Output bis zu deren Verifikation eindeutig auf allen Zerlegungsebenen identifizier- und zuordenbar sein müssten.
Wenn ich mir Ihre Erklärungen in diesem Thread und allgemein zur 62304 und der Verifikation von SW Items/Units anschaue, dann gewinne ich den Eindruck, dass meine Interpretation etwas über das Ziel hinausschießt, was vermutlich auf Missverständnissen meinerseits beruht. Meine Frage an der Stelle:
Wenn es auf Komponenten-Level (z.B. für SW Units) eigentlich nur noch Design Ouput und keine Design Input gibt, muss ich jedes Design Output Element auf SW Unit Level eindeutig identifizierbar machen und zu jedem solchen Element (direkte) formale Traceability zu einem Test Case auf SW Unit Level herstellen, der diese Design Entscheidung verifiziert? Das wirkt etwas merkwürdig, weil man ja eigentlich gegen Design Input verifiziert und nicht gegen Design Output?
Oder wäre der richtige Ansatz, dass man nur per Design Review verifiziert, dass die dokumentierten Design Entscheidungen (also der Design Output) den Anforderungen auf der Design Input Seite folgen?
Die Durchführung von SW Unit Test würde man dann nur als „allgemeines“ Akzeptanzkriterium definieren (z.B. mit einer Anforderung an die erwartete Code Coverage und einem formalen Review, dass die Tests das Gesamtdesign auch abdecken), ohne dass man hier für jeden Unit Test explizite und granulare Traceability herstellt.