Wie man Heisenberg-Tests repariert

Wie man Heisenberg-Tests repariert

Avatar von Eric

Der Test war gerade noch rot, aber jetzt ist er wieder grün. Gestern Nacht ist der Build fehlgeschlagen – aber jetzt funktioniert er wieder. Merkwürdig, die Änderungen in diesem Branch haben gar nichts mit dem Test zu tun …

Klingen diese Äußerungen vertraut?

Auf Geisterjagd in der Test-Suite

Ich habe ein Geständnis abzulegen: Ich liebe es, mir Konferenzvideos anzuschauen. Und manchmal binge ich ganze Konferenzen. Ich kenne keinen besseren Weg, sich mal eben so alle aktuellen Entwicklungen in einem Feld anzuschauen. Es gibt außerdem eine ganze Reihe von verschiedenen Meinungen und Perspektiven und – seien wir mal ehrlich – Popcorn-Stimmung, wenn andere von ihren IT-Katastrophen erzählen und wie sie sie bewältigt haben. Und hin und wieder findet man ein verstecktes Juwel. 

Das sind die Vorträge, die ich immer wieder zitiere, weil sie nützliche Informationen so geschickt gesammelt und dargestellt haben, wie ich sie an keinem anderen Ort gefunden habe. Ich spreche heute von Sonja Peterson’s Vortrag Fixing Flaky Tests like a Detective von der Railsconf 2019. Und es sind diese Juwelen, die ich über Jahre hinweg immer wieder zitiere.

Verhaften Sie die üblichen Verdächtigen!

Tests sind kaputt, weil wir Komplexität nicht mental umrissen haben. Wenn sie hin und wieder ohne erkennbare Kausalzusammenhänge fehlschlagen, kann der Fehler irgendwo liegen. Nicht nur im Code, sondern auch in den Tiefen der Dependencies, in der Maschinenumgebung, vielleicht auch beim Anwender?

Es ist leicht, die Flinte ins Korn zu werfen angesichts des fehlenden Nähwerkzeugs das irgendwo in dieser ungeordneten Menge getrockneten Grases liegt.

Aber! Es gibt einige Dinge, die man sich genauer anschauen könnte …

A steht für Async

Sind asynchrone Prozesse vorhanden, die eine Race Condition auslösen könnten? Ein ganz populärer Kandidat, wenn es um UI-Tests mit z. B. playwright geht. Lässt sich durch speziell platzierte sleep-Statements ein fehlschlagender Test auslösen? Wenn ja, dann hilft es sehr, konkrete awaits in den Testcode einzubauen. 

(Bitte sleep nach dem debuggen wieder entfernen, danke!)

U steht für Unordered Collections

Oft haben wir es mit Datenstrukturen zu tun, die keinerlei Garantie für die Anordnung ihrer Inhalte abgeben. Gerade Message Queues wie Kafka sind bekannt dafür. Wenn wir sie behandeln wie strikt sortierte Arrays, kommen wir leicht zu einem Test, der manchmal fehlschlägt.

T steht für Time

Zeitzonen und Datumsgrenzen können leicht zu unvorhergesehenen Zuständen führen. Das Prinzip eines Zeitstempels beim Speichern von Datenbankeinträgen kann leicht eine zeitliche Abhängigkeit einführen. Schlagen die Tests eventuell immer zu einer bestimmten Uhrzeit fehl? Haben wir an Schaltjahre gedacht und regionale Feiertage? Und noch einmal: Ist das hier wirklich GMT oder doch irgendeine lokale Zeitzone?

O steht für Order Dependency

Haben wir eventuell das FIRST-Prinzip verletzt und Abhängigkeiten zwischen unseren Tests eingeführt, ohne es zu beabsichtigen? Oft schleichen sich in setup– und before-Methoden Dinge ein, die durch vorhergegangene Tests ein State gesammelt haben. Vor allem auch Browserautomatisierung ist eine populäre Ursache für „leaky state“.

R steht für Randomness

Zufallszahlen sollten niemals in einem Test vorkommen. Jedes Ausführen von Zufallsgeneratoren sollte durch spezifische Zahlen unterbunden werden. Generell sind für einen Test nur drei Zahlen wirklich interessant: Null, eins und viele (angelehnt an die Zero-One-Infinity Rules, die auf Willem van der Poel zurückgeht). Davon abgesehen liefern viele Test-Frameworks die Seeds aus, mit denen die Tests gelaufen sind. Ein gefundenes Fressen für den Debugger!

Geburt eines Akronyms

AUTOR? TAURO? Wie auch immer man sich die „Üblichen Verdächtigen“ merkt, der emotionale Effekt wird derselbe sein: Anstelle von Hilflosigkeit angesichts des komplexen States haben wir nun Anhaltspunkte.

Fazit: Bitte nicht wegschauen!

Je nachdem wie hart der Druck im Projekt ist, hat man gerne den kurz fehlgeschlagenen Test „nicht gesehen“. Er „funktioniert ja jetzt“. Vielleicht war es nur der Wind ..? 

Logisch gesehen wissen wir, dass der beste Zeitpunkt etwas zu tun immer genau jetzt ist. Und sei es nur, dass wir ein Ticket anlegen, dass darauf hinweist. Zu allermeist lassen sich „Flaky Tests“ als solche gruppieren und unter genaue Beobachtung stellen, bis man dann doch die Stelle findet, an der man die lockere Schraube anziehen kann.

Avatar von Eric

Kommentare

Schreibe einen Kommentar

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


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.