Was ist ein Mutationstest? (Beispiel)
โก Intelligente Zusammenfassung
Beim Mutation Testing werden absichtlich kleine Fehler in den Quellcode eingefรผhrt und anschlieรend die bestehende Testsuite gegen jede fehlerhafte Version ausgefรผhrt, um zu messen, ob diese Tests ausreichend sind, um die รnderung zu erkennen.
Was ist ein Mutationstest?
Mutationstests Mutationstests sind eine Art Softwaretest, bei dem bestimmte Anweisungen des Quellcodes verรคndert (mutiert) werden, um zu รผberprรผfen, ob die Testfรคlle Fehler im Quellcode finden kรถnnen. Ziel des Mutationstests ist es, die Robustheit der Testfรคlle sicherzustellen, sodass sie bei verรคndertem Quellcode fehlschlagen.
Die in einem mutierten Programm vorgenommene รnderung muss extrem gering sein, damit sie das Gesamtziel des Programms nicht beeintrรคchtigt. Mutationstests werden auch als fehlerbasierte Teststrategie bezeichnet, da sie das gezielte Erzeugen eines Fehlers im Programm beinhalten. Es handelt sich um eine Form des Mutationstests. Weiร Box Tests das hauptsรคchlich angewendet wird wรคhrend Unit Tests.
Mutation Testing wurde 1971 in einer studentischen Arbeit von Richard Lipton vorgeschlagen und 1978 in der Arbeit โHints on Test Data Selectionโ von DeMillo, Lipton und Sayward formalisiert. Aufgrund des damaligen Rechenaufwands verlor es an Bedeutung, hat aber seither fรผr Sprachen wie โฆ wieder an Relevanz gewonnen. Java, C#, Python, JavaSkript und XML.
Wie fรผhrt man einen Mutationstest durch?
Im Folgenden sind die Schritte zur Durchfรผhrung eines Mutationstests, auch Mutationsanalyse genannt, aufgefรผhrt:
Schritt 1: Fehler werden in den Quellcode des Programms eingefรผhrt, indem zahlreiche Versionen, sogenannte Mutanten, erstellt werden. Jede Mutante sollte genau einen Fehler enthalten, und das Ziel ist es, die Mutantenversion zum Absturz zu bringen, wodurch die Wirksamkeit der Testfรคlle demonstriert wird.
Schritt 2: Die Testfรคlle werden sowohl auf das Originalprogramm als auch auf das mutierte Programm angewendet. Testfall sollte ausreichend sein und ist darauf ausgelegt, Fehler in einem Programm zu erkennen.
Schritt 3: Vergleichen Sie die Ergebnisse des Originalprogramms und des mutierten Programms.
Schritt 4: Wenn das Originalprogramm und das mutierte Programm unterschiedliche Ausgaben erzeugen, wird das mutierte Programm durch den Testfall beendet. Daher ist der Testfall ausreichend, um die รnderung zwischen dem Originalprogramm und dem mutierten Programm zu erkennen.
Schritt 5: Wenn das Originalprogramm und das mutierte Programm die gleiche Ausgabe erzeugen, bleibt die mutierte Version aktiv. In solchen Fรคllen mรผssen effektivere Testfรคlle erstellt werden, die alle mutierten Versionen eliminieren.
Das untenstehende Diagramm tracEs sind immer die gleichen fรผnf Schritte, vom ursprรผnglichen Programm รผber die Erzeugung von Mutanten bis hin zum Urteil, ob man getรถtet wurde oder รผberlebt hat.
Wie erstellt man Mutantenprogramme?
Eine Mutation ist nichts anderes als eine einzelne syntaktische รnderung an einer Programmanweisung. Jedes mutierte Programm sollte sich vom Originalprogramm durch genau eine Mutation unterscheiden.
| Ursprรผngliches Programm | Mutantenprogramm |
| Wenn (x>y) Drucken Sie โHalloโ Else Drucken Sie โHalloโ |
Wenn (x Drucken Sie โHalloโ Else Drucken Sie โHalloโ |
Im obigen Beispielpaar hat sich lediglich der Vergleichsoperator geรคndert. Dennoch wird in einem Testfall, in dem x grรถรer als y ist, nun โHiโ anstelle von โHelloโ ausgegeben. Die Abbildung verdeutlicht diese eine syntaktische รnderung.
Was muss in einem Mutantenprogramm geรคndert werden?
Es gibt verschiedene Techniken zur Erzeugung von Mutationsprogrammen. Die drei unten aufgefรผhrten Familien decken die meisten Mutationsoperatoren ab, die in den Tools standardmรครig enthalten sind.
| Operaund Ersatzbetreiber | Ausdrucksmodifikationsoperatoren | Operatoren zur รnderung von Anweisungen |
| Ersetzen Sie den Operanden durch einen anderen Operanden (x durch y oder y durch x) oder durch einen konstanten Wert. | Einen Operator in einer Programmanweisung ersetzen oder einen neuen Operator einfรผgen. | Programmatische Anweisungen werden geรคndert, um mutierte Programme zu erstellen. |
| Ejemplo: Wenn(x>y) ersetzen Sie die x- und y-Werte Wenn(5>y) ersetze x durch die Konstante 5 |
Ejemplo: Wenn(x==y) Wir kรถnnen == durch >= ersetzen und das mutierte Programm wie folgt erhalten: If(x>=y) und Einfรผgen von ++ in die Anweisung Wenn(x==++y) |
Ejemplo: Lรถschen Sie den else-Teil in einer if-else-Anweisung Lรถschen Sie die gesamte if-else-Anweisung, um das Verhalten des Programms zu รผberprรผfen. |
Einige Beispiele fรผr Mutationsoperatoren:
- GOTO-Label-Ersatz
- Ersatz der Rรผckgabeerklรคrung
- Lรถschung der Anweisung
- Einfรผgung unรคrer Operatoren (wie โ und ++)
- Austausch des logischen Connectors
- Vergleichbarer Array-Namensersatz
- Entfernen des else-Teils einer if-else-Anweisung
- Hinzufรผgen oder Ersetzen von Bedienern
- Anweisungsersetzung durch รnderung der Daten
- Datenmodifikation fรผr die Variablen
- รnderung von Datentypen im Programm
OperaTors, die eine Randbedingung berรผhren, รผberleben am hรคufigsten, daher weisen Mutationsergebnisse hรคufig auf Lรผcken in zurรผck. Grenzwertanalyse.
Arten von Mutationstests
In Software EngineeringMutationstests lassen sich grundsรคtzlich in drei Typen unterteilen: Anweisungsmutation, Wertmutation und Entscheidungsmutation.
- Aussagemutation โ Eine Anweisung wird ausgeschnitten, eingefรผgt oder gelรถscht, sodass das Ergebnis die Entfernung einiger Codezeilen sein kann.
- Wertmutation โ die Werte primรคrer Parameter und Konstanten werden verรคndert, beispielsweise durch die รnderung einer Schleifengrenze oder eines Schwellenwerts.
- Entscheidungsmutation โ Kontrollanweisungen werden geรคndert, zum Beispiel umkehrenping ein relationaler Operator oder die Negation einer Bedingung.
Die Werkzeuge gruppieren ihre Operatoren unter diesen drei Kategorien, sodass die Familie, die eine รผberlebende Mutante erzeugt hat, dem Tester mitteilt, welche Art von Assertion fehlt. Eine รผberlebende Entscheidungsmutante markiert รผblicherweise einen ungetesteten Zweig, der sich mit รผberschneidet. Schleifentest.
Automatisierung von Mutationstests
Mutationstests sind manuell extrem zeitaufwรคndig und kompliziert, daher empfiehlt sich der Einsatz von Automatisierungstools, die zudem Kosten sparen. Ein Mutationstest-Tool kompiliert die Mutanten, plant die Testlรคufe, protokolliert, welche Mutante durch jeden fehlgeschlagenen Test beendet wurde, und gibt das Ergebnis aus.
Liste der verfรผgbaren Werkzeuge:
- Stryker โ ein Open-Source-Mutationstest-Framework mit Editionen fรผr JavaDrehbuch und TypeScript (StrykerJS), C# und .NET (Stryker.NET) sowie Scala (Stryker4s).
- PIT, auch PITest geschrieben โ ein Mutationstestsystem fรผr Java und die JVM, die kompilierten Bytecode verรคndert und sich in Maven einbindet und Gradle baut neben JUnit.
Beide werden als Build-Schritt ausgefรผhrt, gehรถren also in denselben Ordner. kontinuierliche integration Pipeline wie der Rest der Automatisierungstests Suite.
Mutations-Score
Der Mutationswert ist definiert als der Prozentsatz der getรถteten Mutanten bezogen auf die Gesamtzahl der Mutanten.
Mutationspunktzahl = (getรถtete Mutanten / Gesamtzahl der Mutanten) * 100
Die Formel ist unten in der Form dargestellt, in der sie die meisten Tools ausgeben.
Testfรคlle gelten als mutationsadรคquat, wenn die Punktzahl 100 Prozent erreicht. In der Praxis muss der Nenner bestimmte Werte ausschlieรen. รคquivalente Mutanten Mutanten, deren verรคnderte Syntax sich exakt wie das Original verhรคlt, kรถnnen von keinem Test eliminiert werden. Daher melden die Tools die Anzahl der eliminierten Mutanten geteilt durch die Summe der eliminierten und รผberlebenden nicht-รคquivalenten Mutanten und รผberlassen es dem Tester, รquivalente zu kennzeichnen.
Experimentelle Ergebnisse haben gezeigt, dass Mutationstests eine effektive Methode sind, um die Eignung von Testfรคllen zu messen. Der Hauptnachteil besteht in den Kosten fรผr die Generierung der Mutanten und die Ausfรผhrung jedes Testfalls gegen jede einzelne Mutante.
Mutationstests vs. Code Abdeckung
Hoch Testabdeckung Das beweist keine aussagekrรคftigen Tests. Zeilen- und Zweigabdeckung protokollieren lediglich, welche Anweisungen ausgefรผhrt wurden, nicht aber, ob anschlieรend etwas verifiziert wurde. Daher gilt ein Test, der eine Methode aufruft und nichts รผberprรผft, dennoch als abgedeckt. Mutationstests schlieรen diese Lรผcke, da ein Mutant nur dann abbricht, wenn eine Assertion tatsรคchlich fehlschlรคgt.
| Aspekt | Code Berichterstattung | Mutationswert |
| Was es misst | Welche Zeilen oder Zweige wurden die Tests ausgefรผhrt? | Welche Fehler wurden durch die Tests aufgedeckt? |
| Empfindlich gegenรผber Behauptungen | Nein โ ein Test ohne Assertions erhรถht trotzdem die Testabdeckung. | Ja โ ein Mutant รผberlebt, wenn keine Behauptung fehlschlรคgt. |
| Kosten eines Laufs | Ein instrumentierter Testlauf | Ein Testlauf pro รผberlebendem Mutanten, bisher also deutlich langsamer. |
| Typische Verwendung | Ein schneller Check bei jedem Commit | Eine eingehendere regelmรครige รberprรผfung kritischer Module |
| Fehlermodus | 100-prozentige Abdeckung ohne wirkliche รberprรผfung | รquivalente Mutanten, die niemals getรถtet werden kรถnnen |
Die beiden Metriken ergรคnzen sich. Die Codeabdeckung erfasst den Code, der nie ausgefรผhrt wurde; der Mutations-Score erfasst den erreichten Code, der nie รผberprรผft wurde. Beide flieรen in dieselbe Datenbank ein. Fehlermanagementprozess, zusammen mit Maรnahmen wie Defektdichte.
Vorteile von Mutationstests
Im Folgenden sind die Vorteile von Mutationstests aufgefรผhrt:
- Es handelt sich um einen leistungsstarken Ansatz, um eine hohe Abdeckung des Quellprogramms zu erreichen.
- Es testet die Testsuite selbst, was kein anderer kann. Softwaretestverfahren tut es direkt.
- Mutationstests bieten Softwareentwicklern ein hohes Maร an Fehlererkennung.
- Die Methode deckt Unklarheiten im Quellcode auf und hat die Fรคhigkeit, Fehler aufzudecken, die bei normalen Programmlรคufen nie gefunden werden.
- Die รผberlebenden Mutanten sind angreifbar: Jeder von ihnen benennt eine bestimmte Zeile und eine bestimmte รnderung, die die Suite nicht bemerkt hat.
- Von diesen Tests profitieren die Kunden, indem sie ein zuverlรคssigeres und stabileres System erhalten.
Nachteile von Mutationstests
Auf der anderen Seite ergeben sich folgende Nachteile beim Mutationstest:
- Mutationstests sind extrem kostspielig und zeitaufwรคndig, da eine groรe Anzahl von mutierten Programmen generiert und kompiliert werden muss.
- Da dieser Vorgang zeitaufwรคndig ist, kann man mit Fug und Recht behaupten, dass diese Tests ohne ein Automatisierungstool nicht durchgefรผhrt werden kรถnnen.
- Jede Mutante wird anhand der gleichen Anzahl von Testfรคllen wie das Originalprogramm geprรผft, daher muss eine groรe Anzahl von Mutanten gegen die gesamte Testsuite ausgefรผhrt werden.
- รquivalente Mutanten kรถnnen durch keinen Test abgetรถtet werden, und ihre Trennung von echten รberlebenden erfordert in der Regel eine manuelle รberprรผfung.
- Da die Methode den Quellcode verรคndert, ist sie nicht anwendbar auf Schwarz Box Tests.
Wann sollte man Mutationstests einsetzen?
Das oben beschriebene Kostenprofil bedeutet, dass Mutationstests selten bei jedem Commit รผber die gesamte Codebasis ausgefรผhrt werden. Sie amortisieren sich dort, wo ein unentdeckter Fehler teuer ist und der zu testende Code klein genug ist, um sich schnell zu verรคndern.
- Sicherheitskritische oder finanzielle Logik โ Zahlungsberechnung, Steuervorschriften und Autorisierungsprรผfungen, bei denen eine unabsichtliche falsche Antwort schlimmer ist als ein Systemabsturz.
- Suiten mit verdรคchtig hoher Abdeckung โ wenn die Abdeckung nahezu 100 Prozent betrรคgt, aber dennoch Fehler auftreten.
- Legacy-Code wird refaktoriert โ Die Ergebnisse der Mutationsanalyse zeigen, ob die bestehenden Tests eine Regression aufdecken wรผrden.
- Bibliotheken und gemeinsam genutzte Komponenten โ ein Fehler in einem wiederverwendeten Komponente multipliziert sich mit jedem Anrufer.
- Teams รผben Testgetriebene Entwicklung โ Die Punktzahl รผberprรผft, ob die zuerst geschriebenen Tests tatsรคchlich funktionieren.
Es lohnt sich in der Regel nicht, auf Wegwerfprototypen, auf dรผnnem Code oder generiertem Code ohne Verzweigungslogik oder auf Testsuiten, die von langsamen Prozessen dominiert werden, zu arbeiten. Integrationstests Das dauert schon Stunden fรผr einen einzigen Durchlauf.
Die meisten Teams beschrรคnken den Testlauf daher auf geรคnderte Dateien, legen einen Schwellenwert fรผr die relevanten Module fest und รผberlassen den weiteren Testlauf dem grรถรeren System. Regressionstests Die Suite trรคgt den Rest der Lebenszyklus von Softwaretests.



