Mutational testing ist die Antwort auf die Frage, wie gut Tests sind.

Für mich persönlich war Mutational testing eine Offenbarung. Nicht ganz so einschlagend wie TDD, aber nahe dran.

An einem einfachen Beispiel möchte ich das Prinzip erläutern, um dann zu beschreiben, wie es in professioneller Weise eingeführt wird.

public class DividableByThree {

 public boolean dividable(int number) {
  return (number%3 == 0);
 }

}

Frage: Warum geschieht die Umsetzung nicht eigentlich durch den Aufruf:

return (number%4 == 0);

Die Antwort liegt auf der Hand. Es wäre falsch.

Nur, welcher unserer Tests bestätigt, dass diese Implementierung falsch ist. Richtig: Keiner.

Wir haben also eine Veränderung oder Mutation unseres Codes erzeugt, die von keinem Test als ungültige Lösung entlarvt wird.
Der Mutant unseres Codes hat die Testserie überlebt (survived). Er konnte nicht getötet werden (killed).

Genau das ist, was Mutation Testing macht.

Es verändert den Quellcode und prüft, ob es einen Test gibt, der die Codeänderung unzulässig macht.

Mutation Coverage with Pitest

Das hier verwendete Tool heißt Pitest. Es erzeugt in dieser einen Zeile bis zu 9 verschiedene Mutationen und läßt unsere Test dagegen laufen. 8 Mutants wurden gekilled; einer hat überlebt (survived).

Trotzdem haben unsere beiden Tests den Code zu 100% abgedeckt und zwar nicht nur in Line Coverage, sondern auch Branch Coverage. Dennoch ist diese Überprüfung noch nicht genug, weil ja eine alternative – offenbar falsche – Implementierung existiert, die nicht stimmt.

Die Lösung liegt natürlich in diesem Fall auf der Hand: Wir ersetzen in unserem ersten Test die Zahl 12 durch 3.

Man kann also durch die Ermittlung der Mutation Coverage die Qualität der Tests steigern.

Zudem zeigt dieses Beispiel sehr schön, dass 100% Test Coverage eben kein Garant für korrekten Code bedeutet, was nicht heißt, dass man keine 100% Coverage erzielen muss. Das wäre noch schlimmer oder zusammengefasst: 100% Test Coverage sind nicht genug.

Das ist für mich immer das beste Argument, wenn es um die Frage geht, wieviel Coverage denn ein sehr gutes Projekt auszeichnet.
Mutational Testing beim Review

Die Erstellung von Mutationen und das Gegenprüfen der eigenen Tests kann nun automatisiert durch ein Tool wie beispielsweise Pitest laufen.

Man kann diese Technik aber auch hervorragend beim Code Review einsetzen und damit den Code und die Tests auf Herz und Nieren prüfen.
Mutators

Die Liste der durch das Tool Pitest verfügbaren und verwendbaren Mutators findet man hier.

Ein paar davon seien exemplarisch genannt, um die eigene Phantasie anzuregen und neue zu erfinden. Evtl. implementiert ihr die auch gleich als Erweiterungen von Pitest.
Conditionals Boundary Mutator

Dieser Mutant bewirkt bei Conditionals , das Miteinschließen bzw. Ausklammern der Grenzen:

Wenn also ein Wert auf <= geprüft wird, probiert der Conditionals Boundary Mutator, wie es mit < aussieht. Oder umgekehrt, wenn > verwendet wurde, mutiert der Code zu >=.
Math Mutator

Der Math Mutator ersetzt mathematische Operation durch andere mathematische Operationen. Also wird aus:


a = b + c;

zum Beispiel:


a = b -c

Das macht er aber natürlich mit einer ganzen Reihe von Operatoren.

Mutational Testing
Markiert in:                            

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.