
Beim Implementieren von Softwaretests kommt häufig die Frage auf, ob die Tests ausreichend oder „gut genug“ sind, um Fehler in der Anwendung angemessen zu erkennen. Eine Methode, die genutzt werden kann, um genau diese Frage zu beantworten, ist Mutationstesten.
Doch was ist eigentlich Mutationstesten?
Mit Mutationstesten kann die Qualität eines Testsets bestimmt werden. Dafür benötigt man als Ausgangslage Softwaretests und die zugehörige Anwendung. Zusätzlich entscheidet man sich typischerweise für ein konkretes Tool zum Mutationstesten. Dies kann zum Beispiel der „Stryker Mutator“ für Anwendungen in JavaScript, TypeScript, C# und Scala oder „Pitest“ für Java-Anwendungen sein.
Tool-übergreifend ist der Prozess des Mutationstestens sehr ähnlich. Die Tools implementieren verschiedene Mutationsoperatoren. Ein Mutationsoperator ist eine Transformationsregel, die beschreibt, wie ein kleiner Fehler in die Anwendung eingebaut werden kann. Dies kann zum Beispiel ein Wechsel eines Plus- zu einem Minus-Zeichen oder ein Wechsel des booleschen Werts „true“ zu „false“ sein. Das Tool wendet die Mutationsoperatoren auf die Anwendung an und erstellt dadurch viele sogenannte „Mutanten“ der Anwendung. Jeder Mutant entspricht quasi einer Kopie der Original-Anwendung, in die durch einen Mutationsoperator ein Fehler eingebaut wurde.
Im Folgenden werden nun auf jedem Mutanten die existierenden Tests ausgeführt. Dabei wird geschaut, ob die Tests den eingebauten Fehler erkennen können. Können sie den Fehler erkennen, sagt man, dass der Mutant „getötet“ wurde. Waren die Tests nicht in der Lage, den eingebauten Fehler zu erkennen, hat der Mutant „überlebt“. Die Ergebnisse dazu, welche Mutanten überlebt haben und welche getötet wurden, werden typischerweise von den Tools in einer Art Report für den Entwickler aufbereitet. Dieser Report kann dann von dem Entwickler genutzt werden, um das Testset weiter zu verbessern. Konkret können zum Beispiel weitere Testfälle hinzugefügt werden, die zusätzliche Mutanten töten sollen. Nicht immer ist es möglich, jeden Mutanten zu töten. Mutanten, die nicht getötet werden können, weil sie trotz Änderung immer noch fachlich korrektem Code entsprechen, werden „äquivalente Mutanten“ genannt.
Eine zentrale Kennzahl, die beim Mutationstesten genutzt wird, um die aktuelle Testqualität abzubilden, ist der sogenannte „Mutation Score“. Er entspricht dem Anteil von getöteten Mutanten an der Gesamtanzahl der Mutanten ohne den äquivalenten Mutanten. Die Formel sieht also wie folgt aus:
Der Mutation Score wird häufig als Prozentzahl dargestellt. Je näher er an die 100% kommt, desto besser. Anstatt einen Mutationsscore von 100% anzustreben, ist es auch gut möglich, sich als Team das Ziel zu setzen, überall eine gewisse Mindestgrenze wie z.B. 80% zu erreichen.
Und wie könnte ich Mutationstesten in meinem Projekt verwenden?
Ob und wie man Mutationstesten bei sich im Team sinnvoll nutzen kann, ist natürlich sehr situationsabhängig. Vor allem jedoch in Situationen, in denen es essenziell ist, dass die Tests von sehr hoher Qualität sind, kann sich Mutationstesten auszahlen. Dies kann beispielsweise bei sicherheitskritischen Anwendungen der Fall sein. Doch auch bei weniger kritischen Anwendungen kann Mutationstesten genutzt werden, um einen Eindruck der aktuellen Testqualität zu gewinnen. Denn Mutationstesten kann in verschiedenen Ausmaßen verwendet werden: Vom Anstreben eines Mutationscore von 100%, über das Anstreben von einer Mindestgrenze wie 80%, bis hin zu einem situationsabhängigen, kurzen Prüfen des Mutationscores zur Orientierung kann Mutationstesten in jedem beliebigen Ausmaß verwendet werden.
Bei dem Anwenden von Mutationstesten muss gleichzeitig allerdings auch immer abgewogen werden, ob Aufwand und Nutzen im Verhältnis zueinanderstehen. Denn Mutationstesten kann schnell sehr zeitintensiv werden – sowohl was die Ausführungszeit angeht, da die Testfälle auf jedem einzelnen Mutanten ausgeführt werden müssen, als auch was den Personalaufwand zum Prüfen des Ergebnisses und Verbessern der Testsets angeht. Falls der Zeitaufwand zu groß wird, schlägt die Literatur verschieden Techniken zur Reduktion des Zeitaufwands wie z.B. das Auswählen von nur einer begrenzten Anzahl von Mutationsoperatoren oder Mutanten vor. In der Praxis ist die Anwendbarkeit solcher Techniken allerdings auch stark davon abhängig, ob diese von dem gewählten Tool unterstützt werden.
Fazit
Insgesamt wird deutlich, dass Mutationstesten ein interessanter Ansatz ist, um die Qualität von Testsets zu evaluieren. Situationsabhängig kann entschieden werden, ob in einem Projekt Mutationstesten als neuer Ansatz ausprobiert werden soll. Sowohl vor der Einführung als auch danach ist zu empfehlen, Nutzen und Aufwand gegenüberzustellen und individuell zu entscheiden, ob Mutationstesten für den konkreten Anwendungsfall geeignet ist und in welchem Ausmaß es genutzt werden soll.
zurück zur Blogübersicht