The Chromium Chronicle #2: Der Kampf gegen fehleranfällige Tests

Folge 2: von Vasilii in München (Mai 2019)
Vorherige Folgen

Instabile Tests sind ein häufiges Problem in Chrome. Sie beeinträchtigen die Produktivität anderer Entwickler und werden mit der Zeit deaktiviert. Deaktivierte Tests bedeuten eine geringere Testabdeckung.

Trimmungsphase

Die INHABER von Verzeichnissen sind dafür verantwortlich, Fehler bei ihren instabilen Tests zu beheben. Wenn Sie einen Fehler zu einem instabilen Test erhalten, nehmen Sie sich einige Minuten Zeit und kommentieren Sie, was schiefgelaufen ist. Wenn Sie bei einem alten instabilen Test nicht genau wissen, was schiefgelaufen ist, versuchen Sie, den Test einfach wieder zu aktivieren. Weisen Sie den Programmfehler so bald wie möglich neu zu, wenn es sich eindeutig um ein Problem in einer anderen Komponente handelt. Die Verantwortlichen dieser Komponente sollten den Fehler besser einschätzen,

Debugging-Phase

Zum Korrigieren instabiler Tests ist eine Reihe von Befehlszeilen-Flags hilfreich. Mit --enable-pixel-output-in-tests wird beispielsweise die eigentliche Browser-UI gerendert.

Verwenden Sie Fallback-Tools, wenn der Debugger unzuverlässige Zugriffe verschwindet. Es kann vorkommen, dass der Test beim Debugger nie instabil ist. In diesem Fall können Loganweisungen oder base::debug::StackTrace nützlich sein.

Don'ts

Beachten Sie neben Programmfehlern im Produktionscode auch die häufigsten Gründe für EXPECT__*-Fehler:

  • Falsche Erwartungen (z.B. bedeutet „sichere Seite“ HTTPS; sie kann stattdessen ein lokaler Host sein).
  • Race-Bedingungen, da Tests nicht auf das richtige Ereignis warten.

[Teste nicht die Implementierung][not-implementation], sondern die Funktionsweise.

// It takes 2 round trips between the UI and the background thread to complete.
SyncWithTheStore();
SyncWithTheStore();
CheckTheStore();

Die beiden Umläufe können sich in Zukunft in drei ändern, wodurch der Test instabil wird. Allerdings ist nur der Status des Geschäfts relevant. Verwenden Sie stattdessen einen Beobachter für den Speicher.

Don'ts

Achten Sie auf gängige Muster wie die folgenden:

Submit TestPasswordForm();
// Wait until things settle down.
RunLoop().RunUntilIdle();
CheckCredentialPromptVisible();

Ein Snippet wie das obige aus einem Browsertest ist mit hoher Wahrscheinlichkeit falsch. Es gibt viele Ereignisse, die in verschiedenen Prozessen und Threads auftreten sollten, bevor eine UI angezeigt wird.

Das sollten Sie tun:

So lässt sich das Problem beheben:

SubmitTestPasswordForm();
WaitUntilCredentialPromptVisible();

Die Fehlerbehebung oben ist korrekt, vorausgesetzt, WaitUntilCredentialPromptVisible() prüft die UI nicht. Die Browsertests sollten nicht von externen UI-Ereignissen wie „Fokus verloren“ oder „Fenster wurde im Vordergrund“ abhängen. Stellen Sie sich eine Implementierung vor, bei der die Eingabeaufforderung nur dann angezeigt wird, wenn das Browserfenster aktiv ist. Eine solche Implementierung wäre korrekt, aber die Überprüfung des tatsächlichen Fensters macht den Test instabil.

Post-Fix-Phase

Sobald der Test abgeschlossen ist, kannst du ihn Hunderte Male lokal ausführen. Beobachte das Flakiness-Portal.