Mutation Testing, zweiter Anlauf
2020 habe ich Infection auf ein gewachsenes Shopsystem losgelassen.
Infection baut absichtlich kleine Fehler in PHP-Code ein und prüft, ob die
Tests sie bemerken. Aus einem >= wird ein >, aus einem Plus ein Minus,
aus einer Bedingung ihr Gegenteil. Jede dieser Varianten heißt Mutant.
Stirbt der Mutant, weil ein Test rot wird, hat die Suite ihren Job gemacht.
Überlebt er, hat die Suite ein Loch.
Das Werkzeug hat geliefert. Es fand Löcher, von denen die Coverage nichts ahnte. Abgeschaltet habe ich es trotzdem.
Woran es 2020 wirklich scheiterte
Nicht am Werkzeug. An der Rechnung dahinter. Jeder überlebende Mutant will von einem Menschen angesehen werden. Ist es ein echtes Loch? Dann fehlt ein Test, und den muss jemand schreiben. Oder ist es eine äquivalente Mutante, eine Änderung, die das Verhalten gar nicht ändert und die kein Test der Welt fangen kann? Dann war die Analyse umsonst.
Beides kostet Entwicklerzeit. Bei jedem Lauf, nicht einmalig. Ein guter Test kostete damals ohnehin schon mehr als der Code, den er prüft. Mutation Testing setzte noch eine Schicht Handarbeit obendrauf: die Löcher finden, die Löcher bewerten, die Löcher stopfen. Das Budget dafür gab es nicht. Also flog die Prüfung raus, und die Coverage-Zahl blieb als einzige Wahrheit übrig.
Was sich seit damals gedreht hat
Heute schreibt in meinem Nebenprojekt Calculoria eine KI den Großteil der Tests. Rund 5.000 Stück sind so entstanden. Die Abdeckung ist hoch, und genau deshalb traue ich ihr weniger denn je. Ein Sprachmodell erzeugt mühelos Tests, die jede Zeile ausführen und kaum eine prüfen. Smoke-Tests auf Steroiden. Die Coverage sieht tadellos aus und misst doch nur, dass der Code gelaufen ist. Nicht, dass ihn jemand festgenagelt hat.
Damit ist Mutation Testing vom Luxus zur fehlenden Kontrolle geworden. Es ist das einzige mir bekannte Verfahren, das die Testsuite selbst befragt: Würdet ihr es überhaupt merken, wenn der Code kaputt wäre?
Und die Rechnung von 2020 hat sich umgedreht. Die teure Hälfte, das Bewerten und Stopfen der Löcher, ist heute delegierbar. Ein überlebender Mutant ist eine präzise Arbeitsanweisung an einen Agenten: Hier ist die Codezeile, hier die Änderung, die niemand bemerkt hat. Schreib den Test, der sie bemerkt. Das kostet Tokens, keine Entwicklerwochen.
Der Versuchsaufbau
Genau das probiere ich jetzt in Calculoria aus. Der Plan:
-
Baseline messen: Mutation Score auf den Kernmodulen, einmal komplett. Die Zahl sagt, wie viel von der schönen Abdeckung echt ist.
-
Überlebende Mutanten als Backlog: Jeder Mutant wird ein Arbeitsauftrag für einen Agenten. Test schreiben, Mutant töten, Gate grün.
-
Nachmessen: Score danach, Token-Kosten pro getötetem Mutanten, Zeitaufwand, und der Anteil äquivalenter Mutanten, der übrig bleibt.
Drei Hypothesen gehen mit ins Rennen:
H1: Der Mutation Score liegt deutlich unter dem, was die Coverage verspricht. Wenn nicht, war mein Misstrauen unbegründet. Auch das wäre ein Ergebnis.
H2: Das Stopfen der Löcher rechnet sich diesmal. Tokens pro Mutant statt Entwicklerstunden pro Mutant. 2020 war das der Killer, heute sollte es der billigste Teil sein.
H3: Ein harter Rest bleibt Handarbeit. Äquivalente Mutanten kann kein Agent töten, er kann sie höchstens erkennen und begründen. Wie groß dieser Rest ist, entscheidet über die Alltagstauglichkeit.
Was schiefgehen kann
Es ist ein Experiment, und ich rahme es ehrlich als eines. Die Laufzeit auf einer Suite dieser Größe kann unangenehm werden, denn Mutation Testing führt die Tests für jeden Mutanten erneut aus. Ein anderes Risiko macht mir mehr Sorgen: Ein Agent, der auf den Mutation Score optimiert, kann Tests schreiben, die Mutanten töten und trotzdem nichts Sinnvolles prüfen. Auch ein Mutation Score ist nur eine Metrik, und Metriken kann man bedienen. Die Stichprobe von Hand bleibt deshalb im Aufbau. Als Kontrolle der Kontrolle.
Die Ergebnisse schreibe ich hier auf, mit echten Zahlen, auch wenn sie gegen mich sprechen. 2020 hat das Experiment gegen mein Budget verloren. Mal sehen, gegen wen es diesmal verliert.
Klingt nach deinem Thema? Schreib mir. Im Erstgespräch klären wir unverbindlich, ob und wie ich helfen kann.