6
Keine neue Idee
• Vorgeschlagen von Richard Lipton 1971
• Veröffentlicht von DeMillo, Lipton and Sayward in IEEE Computer, 11(4):34-41. April 1978.
• In many cases tests of a program that uncover simple errors are also effective in uncovering much more complex errors. This so-called coupling effect can be used to save work during the testing process.
• 1975 stellt IBM den ersten tragbaren Computer vor (IBM 5100)
• 1976 bringt Apple den Apple I auf den Markt
• => aufregende Zeiten, überschaubare Rechenleistung
7
Fun facts
• X-Men erscheinen erstmals 1963
• Aber erst seit ca. 1975 erfolgreich
• Den Vortragenden gibt es erst seit 1982
• Wie wir sehen werden brauchte auch unser Thema etwas Anlauf
8
Warum Testen? Warum ich/wir Tests schreiben…
• „Vom Feeling her hatte ich ein gutes Gefühl.“ – Andreas Möller
• Das gute Gefühl Qualität zu liefern
• Was will ich denn eigentlich implementieren?
• Besseres Design/APIs
• Regulatorien wie etwa IEC 62304 (Medizingeräte-Software)
• Fordert Tests auf allen „Ebenen“ Unit-Test, Integration und System
9
Nur…
• Spaß am Testschreiben kann sich in Grenzen halten
• Aufwändig, kompliziert, …
• Tests mitunter ein Biest für sich
• Bringen eigene Konzepte und Strukturen mit sich
• Zuweilen fehlt es auch an Wissen
• „Tests sind für uns alle Neuland…“
• Unseren Code kann man ja gar nicht testen
• Werden mitunter stiefmütterlich behandelt
• Selbst in Code-Reviews gerne mal überflogen
10
Antworten finden…
• Wie gut sind meine Unit Tests?
• Wie gut ist meine Test-Abdeckung?
• Welche Tests fehlen mir eventuell?
11
Was brauche ich für Mutation Testing?
Code wird durch
Mutanten versehen
Sollte zu Beginn
der Prozedur
„grün“ sein.
Wie sonst auch
immer… ;-)
12
Schritte durch die Mutanten Jagd
1. Mutanten (Fehler) werden erzeugt
2. Pro Mutant werden die UTs ausgeführt
1. Wird ein Test „rot“, wurde der Mutant getötet
2. Kippt keiner, hat der Mutant überlebt
3. Auswertung des getöteten Prozentsatzes an Mutanten
13
MT vs. Traditionelle Testabdeckung
• Testabdeckung betrachtet im Vergleich „nur“ welcher Code
ausgeführt wurde
• Nicht jedoch ob die Tests auch in der Lage sind Fehler zu finden
• “As it is actually able to detect whether each statement is
meaningfully tested, mutation testing is the gold standard
against which all other types of coverage are measured.”
pitest.org
14
Unterschiedliche Mutanten Klassen
• Conditionals Boundary Mutator
• Increments Mutator
• Invert Negatives Mutator
• Math Mutator
• Negate Conditionals Mutator
• Return Values Mutator
• Void Method Calls Mutator
• Constructor Calls Mutator
• Inline Constant Mutator
• Non Void Method Calls Mutator
• Remove Conditionals Mutator
• Experimental Member Variable Mutator
• Experimental Switch MutatorA
uto
matisch a
n
Zu
schaltbar
15
Mutatoren
Original Änderung
< <=
<= <
> >=
>= >
Conditionals Boundary Mutator
Original Änderung
++ --
Increments Mutator
Invert Negatives Mutator
Original Änderung
public float negate(final float i) { return -i; }
public float negate(final float i) { return i; }
17
Mutatoren III
Return Values Mutator
Original Änderung
Boolean True bzw. false
Int, byte, short 1 oder 0, entgegen dem Original
Long X+1
Float, double -(x+1.0)
ObjectsNull bzw. RuntimeException für null-Werte
Void Method Call Mutator
Original Änderung
public int foo() { int i = 5; doSomething(i); return i; }
public int foo() { int i = 5; return i; }
18
Wie funktioniert das Ganze?
• Abhängig von der Technologie
• Pitest:
• Änderungen erfolgen am Bytecode
• Zeilennummern und Quelldateiname benötigt
• Mutate.py (Skript für C-Code-Mutationen):
• Generiert ein verändertes .c-File
19
Herausforderungen
• Leistungsintensiv
• Erst mit aktueller Rechenleistung überhaupt einsetzbar
Unit-Tests Laufzeit
2658 8 min 53 s
2428 7 min 39 s
MT-Tests Laufzeit
218 7 min 44s
20
Herausforderungen
- Timings
=======================================
> scan classpath : 1 seconds
> coverage and dependency analysis : 2 minutes and 33 seconds
> build mutation tests : 1 seconds
> run mutation analysis : 5 minutes and 7 seconds
> Total : 7 minutes and 44 seconds
================================================================================
- Statistics
================================================================================
>> Generated 5336 mutations Killed 3034 (57%)
>> Ran 9923 tests (1.86 tests per mutation)
21
Herausforderungen II
• False-Positives
• Sprachunterstützung von wechselnder Qualität
• Einsatz in aktuellem Projekt schwer möglich: JavaScript
Transpilation
22
Lösungsansätze
• Mehr Power (CPU, Threads)
• Nur zu gewissen Zeitpunkten nutzen
• Auf bestimmte Tests beschränken
• Nur bestimmte Mutatoren aktivieren
• PIT: Incremental analysis
• Optimierungsversuch mit Annahmen über Änderungen