Ein Flaky Test besteht und scheitert am selben Code. Zwischen den beiden Durchläufen hat sich nichts geändert außer dem Timing, der Reihenfolge oder etwas außerhalb des Tests, an das niemand gedacht hat.

Er ist schlimmer als ein Test, der immer scheitert, und das ist keine Redewendung. Ein Test, der immer scheitert, ist bis zum Mittagessen repariert. Ein Test, der in einem von zehn Durchläufen scheitert, bringt einem ganzen Team bei, die Schaltfläche zum Neustarten zu drücken, und sobald diese Gewohnheit besteht, muss jeder echte Fehlschlag mit dem Rauschen um die Aufmerksamkeit von irgendjemandem konkurrieren.

Was Flakiness kostet

Sie trainiert Menschen darauf, Rot zu ignorieren. Beim ersten Mal, wenn ein Build scheitert, sieht jemand nach. Beim zwanzigsten Fehlalarm ist die Reaktion ein Neustart und ein Schulterzucken, und eine echte Regression bekommt dasselbe Schulterzucken.

Sie versteckt sich in der Menge. Eine Suite mit einem Dutzend unzuverlässiger Tests scheitert oft genug, dass niemand einen unzuverlässigen Fehlschlag von einem echten unterscheiden kann, ohne ihn zu öffnen, also öffnet ihn niemand.

Sie macht die Suite langsamer und zugleich weniger vertrauenswürdig. Neustarts kosten jeweils Minuten; der Zweifel kostet mehr.

Woher Flakiness kommt

Fast alles davon ist eines von fünf Dingen.

Auf das Falsche warten. Der mit Abstand häufigste Fall in Browsertests. Der Test fragt, ob etwas sichtbar ist, während es noch eingeblendet wird, oder prüft einen Zustand, den die Oberfläche einen Sekundenbruchteil später erreicht. Er besteht auf einer schnellen Maschine und scheitert auf einem ausgelasteten Build-Server, also genau auf der Maschine, auf der Sie nicht debuggen können.

Reihenfolgeabhängigkeit. Ein Test, der nur besteht, nachdem ein anderer gelaufen ist, weil dieser den Datensatz angelegt, den Zustand gesetzt oder etwas hinterlassen hat. Lassen Sie die Suite in einer anderen Reihenfolge oder parallel laufen, und sie bricht zusammen.

Geteilter Zustand. Eine Datenbankzeile, ein zwischengespeicherter Wert, eine Datei auf der Platte, eine Uhr. Zwei Tests, die dieselbe Fixture benutzen, laufen irgendwann nah genug beieinander, um sich gegenseitig zu stören.

Zeit. Alles, was auf das heutige Datum prüft, überschreitet irgendwann Mitternacht; alles mit einem Timeout scheitert unter Last; alles, was von der Reihenfolge zweier Ereignisse ohne Ordnungsgarantie abhängt, ist ein Münzwurf, den Sie noch nicht bemerkt haben.

Die Außenwelt. Ein Test, der ein echtes Netzwerk, einen echten Drittanbieterdienst oder eine echte Uhr erreicht, hat sich die Verfügbarkeit von jemand anderem geliehen.

Der Fehler, der die meisten davon verbirgt

Der rote Faden in den Timing-Fällen ist es wert, für sich genannt zu werden, denn er verändert, wie Sie die Prüfung schreiben.

Auf einen Übergang warten
Prüfen, dass die Schaltfläche ihre Ruhebeschriftung zeigt, während die Animation, die den vorherigen Zustand aufräumt, noch läuft
Auf einen Zustand warten
Prüfen, dass die Klasse "copied" verschwunden ist, und erst dann, dass die Ruhebeschriftung da ist

Das erste ist ein Wettlauf zwischen der Geduld des Test-Frameworks und dem Timer der Oberfläche. Es besteht auf einer ruhigen Maschine und scheitert auf einer beschäftigten, und die Fehlermeldung ist eher verwirrend als aufschlussreich: das Element ist da, mit dem richtigen Text, und einfach noch nicht sichtbar.

Dieses Beispiel ist echt - es ist ein Test in dieser Codebasis, und er ist genau einmal gescheitert, auf einem ausgelasteten Runner, bei einem Commit, der zwei Bilddateien geändert hat.

Was man mit einem macht

Reparieren Sie ihn nicht, indem Sie länger warten. Ein globales Timeout hochzusetzen verlangsamt den Fehlerpfad jedes anderen Tests und verbirgt den nächsten Wettlauf, statt ihn zu beseitigen. Das ist, als würde man die Musik lauter drehen.

Löschen Sie ihn aber auch nicht, jedenfalls nicht als Erstes. Ein Flaky Test zeigt meistens auf etwas Echtes: einen echten Wettlauf im Produkt, eine Oberfläche, die Fertigstellung meldet, bevor sie fertig ist, eine geteilte Ressource, die zwei Dinge benutzen. Den Test zu reparieren heißt manchmal, die Anwendung zu reparieren.

Quarantäne, dann Korrektur, mit Frist. Nehmen Sie ihn aus der blockierenden Suite, damit er aufhört, Menschen das Ignorieren von Rot beizubringen, und setzen Sie ein Datum. Quarantäne ohne Frist ist Löschen mit zusätzlichen Schritten und schlechterem Gewissen.

Zählen Sie sie. Ein Team, das nicht sagen kann, wie viele Flaky Tests es hat, erfährt es, wenn die Zahl groß ist. Wenn Ihr Runner Neustarts aufzeichnet, ist das die Zahl, die man beobachtet.

Wenn die Flakiness am Produkt liegt

Manchmal hat der Test recht und die Software ist unzuverlässig: eine Anfrage, die gelegentlich in falscher Reihenfolge ankommt, eine Oberfläche, die “gespeichert” sagt, bevor das Speichern abgeschlossen ist, ein Job, der normalerweise fertig ist, bevor die Seite neu lädt.

Das sind echte Defekte, und sie sind elend zu melden, denn per Definition treten sie nicht jedes Mal auf. Was sie für jemand anderen nachvollziehbar macht, ist der Kontext des gescheiterten Durchlaufs und nicht eine Beschreibung der zehn, die durchgelaufen sind.

Session Replay

Kostenlose Chrome-Erweiterung. Ein Klick auf der Seite, die sich falsch verhält, erfasst den Screenshot, die Konsole und das Netzwerkprotokoll und gibt Ihnen einen Link, den Sie ins Ticket einfügen können.

Erweiterung holen

Bei einem sporadischen Defekt sagen Sie, wie oft er auftritt und was Sie gerade taten, als er auftrat - “dreimal bei etwa zwanzig Versuchen, immer direkt nach dem Speichern” ist weit nützlicher als die Beschreibung eines einzelnen Vorfalls. Der Leitfaden zum Fehlerbericht deckt den Rest ab.

Die kurze Fassung

Ein Flaky Test scheitert an unverändertem Code, und seine eigentlichen Kosten sind, dass er Menschen beibringt, Fehlschläge zu ignorieren. Die meisten sind ein Test, der auf einen Übergang statt auf einen Zustand wartet, eine Reihenfolgeabhängigkeit oder geteilter Zustand. Beheben Sie die Ursache statt des Timeouts, stellen Sie mit Frist unter Quarantäne statt auf unbestimmte Zeit, und nehmen Sie die Möglichkeit ernst, dass der Test recht hat und die Software die unzuverlässige ist.