t.Log()
wird erst nach Abschluss des Tests angezeigt. Wenn Sie also versuchen, einen Test zu debuggen, der hängt oder schlecht funktioniert, müssen Sie ihn verwenden fmt
.
Ja, das war bis Go 1.13 (August 2019) der Fall.
Und das folgte in golang.org
Ausgabe 24929
Betrachten Sie die folgenden (dummen) automatisierten Tests:
func TestFoo(t *testing.T) {
t.Parallel()
for i := 0; i < 15; i++ {
t.Logf("%d", i)
time.Sleep(3 * time.Second)
}
}
func TestBar(t *testing.T) {
t.Parallel()
for i := 0; i < 15; i++ {
t.Logf("%d", i)
time.Sleep(2 * time.Second)
}
}
func TestBaz(t *testing.T) {
t.Parallel()
for i := 0; i < 15; i++ {
t.Logf("%d", i)
time.Sleep(1 * time.Second)
}
}
Wenn ich laufe go test -v
, erhalte ich keine Protokollausgabe, bis alles TestFoo
erledigt ist , dann keine Ausgabe, bis alles TestBar
erledigt ist, und wieder keine Ausgabe mehr, bis alles TestBaz
erledigt ist.
Dies ist in Ordnung, wenn die Tests funktionieren, aber wenn es einen Fehler gibt, gibt es einige Fälle, in denen das Puffern der Protokollausgabe problematisch ist:
- Wenn ich lokal iteriere, möchte ich in der Lage sein, eine Änderung vorzunehmen, meine Tests auszuführen, zu sehen, was in den Protokollen sofort passiert, um zu verstehen, was vor sich geht, STRG + C zu drücken, um den Test bei Bedarf vorzeitig zu beenden, eine weitere Änderung vorzunehmen und erneut zu ändern Führen Sie die Tests aus und so weiter.
Wenn TestFoo
es langsam ist (z. B. ein Integrationstest), erhalte ich bis zum Ende des Tests keine Protokollausgabe. Dies verlangsamt die Iteration erheblich.
- Wenn
TestFoo
es einen Fehler gibt, der dazu führt, dass er hängen bleibt und nie abgeschlossen wird, erhalte ich überhaupt keine Protokollausgabe. In diesen Fällen t.Log
und t.Logf
sind überhaupt nicht von Nutzen.
Dies macht das Debuggen sehr schwierig.
- Darüber hinaus erhalte ich nicht nur keine Protokollausgabe, sondern wenn der Test zu lange hängt, beendet entweder das Go-Test-Timeout den Test nach 10 Minuten, oder wenn ich dieses Timeout erhöhe, beenden viele CI-Server auch Tests, wenn keine vorhanden sind Protokollausgabe nach einer bestimmten Zeit (z. B. 10 Minuten in CircleCI).
Jetzt sind meine Tests beendet und ich habe nichts in den Protokollen, was mir passiert wäre.
Aber für (möglicherweise) Go 1.14 (Q1 2020): CL 127120
Testen: Stream-Protokollausgabe im ausführlichen Modus
Die Ausgabe ist jetzt:
=== RUN TestFoo
=== PAUSE TestFoo
=== RUN TestBar
=== PAUSE TestBar
=== RUN TestGaz
=== PAUSE TestGaz
=== CONT TestFoo
TestFoo: main_test.go:14: hello from foo
=== CONT TestGaz
=== CONT TestBar
TestGaz: main_test.go:38: hello from gaz
TestBar: main_test.go:26: hello from bar
TestFoo: main_test.go:14: hello from foo
TestBar: main_test.go:26: hello from bar
TestGaz: main_test.go:38: hello from gaz
TestFoo: main_test.go:14: hello from foo
TestGaz: main_test.go:38: hello from gaz
TestBar: main_test.go:26: hello from bar
TestFoo: main_test.go:14: hello from foo
TestGaz: main_test.go:38: hello from gaz
TestBar: main_test.go:26: hello from bar
TestGaz: main_test.go:38: hello from gaz
TestFoo: main_test.go:14: hello from foo
TestBar: main_test.go:26: hello from bar
--- PASS: TestFoo (1.00s)
--- PASS: TestGaz (1.00s)
--- PASS: TestBar (1.00s)
PASS
ok dummy/streaming-test 1.022s
Es ist in der Tat in Go 1.14, wie Dave Cheney in " go test -v
Streaming Output " bestätigt:
In Go 1.14 go test -v
wird die t.Log
Ausgabe sofort gestreamt, anstatt sie bis zum Ende des Testlaufs zu horten .
Unter Go 1.14 werden die Zeilen fmt.Println
und verschachtelt , anstatt auf den Abschluss des Tests zu warten. Dies zeigt, dass die Testausgabe bei Verwendung gestreamt wird.t.Log
go test -v
Vorteil laut Dave:
Dies ist eine hervorragende Verbesserung der Lebensqualität für Tests im Integrationsstil, die häufig über einen längeren Zeitraum wiederholt werden, wenn der Test fehlschlägt.
Durch das Streamen der t.Log
Ausgabe können Gophers diese Testfehler beheben, ohne warten zu müssen, bis der gesamte Test abgelaufen ist, um die Ausgabe zu erhalten.