Problem
Übliche Testmetriken, wie z. B. line coverage und branch coverage, geben lediglich darüber Auskunft, ob Code bei Testausführung erreicht worden ist und nicht unbedingt, ob auch die richtige Funktionalität ausgeführt worden ist.
Dadurch ist es möglich Testcode zu schreiben, der lediglich die Metrik zufriedenstellt, ohne irgendetwas zu testen (Testcases ohne Assertions).
Lösung
Um sich über die Qualität der Tests ein Bild zu machen, kann man Mutationtests verwenden.
Ein Mutationtest führt Unittests auf verschiedenen Mutationen des zu testenden Codes aus.
Es gibt viele verschiedene Mutationsarten, z.B. das Ändern von Conditions (>= wird zu >) oder das Invertieren von boolschen Rückgabewerten.
Beispiel
public class Jambitee {
public boolean isAwake(int amountOfCoffeesToday) {
if (amountOfCoffeesToday >= 1 ) {
return true;
} else {
return false;
}
}
}
public class JambiteeTest {
private Jambitee jambitee = new Jambitee();
@Test
public void isAwakeWith2Coffees() {
assertTrue(jambitee.isAwake(2));
}
@Test
public void isAsleepWithNoCoffee() {
assertFalse(jambitee.isAwake(0));
}
}
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>LATEST</version>
</plugin>
Pitest führt die Tests auf verschiedenen Mutationen aus und erkennt dabei, dass es eine Mutation gibt, die nicht von den Tests abgedeckt ist.
Weiterführende Aspekte
---
Autor: Christof Huber / Software Developer / Business Division Industry & Energy
Zum Toilet Paper #132: Mutationtests mit Pitest (pdf)
Lust, das nächste ToiletPaper zu schreiben? Jetzt bei jambit bewerben!