t.Log()
テストが完了するまで表示されないので、ハングしているテストやパフォーマンスが悪いテストをデバッグする場合は、を使用する必要がありますfmt
。
はい:Go 1.13(2019年8月)まで含まれていました。
そしてそれは問題24929で続いたgolang.org
次の(ばかげた)自動テストを検討してください。
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)
}
}
を実行するとgo test -v
、すべてTestFoo
が完了するまでログ出力がありません。次に、すべてTestBar
が完了するまで出力がありませんTestBaz
。すべてが完了するまで、出力はありません。
テストが機能している場合はこれで問題ありませんが、何らかのバグがある場合は、ログ出力のバッファリングが問題になるいくつかのケースがあります。
- ローカルで反復する場合、変更を加えてテストを実行し、ログで何が起こっているのかをすぐに確認して何が起こっているのかを理解し、必要に応じてCTRL + Cを押してテストを早期にシャットダウンし、もう一度変更して、テストなどを実行します。が遅い
場合TestFoo
(たとえば、それが統合テストである場合)、テストの最後までログ出力がありません。これにより、反復が大幅に遅くなります。
TestFoo
ハングして完了できないバグがある場合、ログ出力はまったく得られません。これらのケースでは、t.Log
とt.Logf
まったく役に立ちません。
これはデバッグを非常に困難にします。
- さらに、ログ出力が得られないだけでなく、テストがハングしすぎると、Goテストのタイムアウトにより10分後にテストが強制終了されるか、タイムアウトを長くすると、多くのCIサーバーでもテストが強制終了されます一定時間後のログ出力(たとえば、CircleCIでは10分)。
だから今私のテストは殺され、何が起こったのかを伝えるためのログには何もありません。
しかし、(おそらく)Go 1.14(2020年第1四半期)の場合:CL 127120
テスト:詳細モードでのストリームログ出力
出力は次のとおりです。
=== 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
デーブ・チェイニーが「go test -v
ストリーミング出力」で証明しているように、それは実際にGo 1.14にあります。
Go 1.14では、テスト実行の最後まで蓄積するのではなく、出力を発生時にgo test -v
ストリーミングしt.Log
ます。
Go 1.14 では、テストが完了するのを待つのではなくfmt.Println
、t.Log
ラインがインターリーブgo test -v
されます。これは、テスト出力がが使用されるときにストリーミングされることを示しています。
デイブによると、利点:
これは、テストが失敗したときに長期間にわたって再試行することが多い統合スタイルのテストでの生活の質を大幅に改善します。
ストリーミングt.Log
出力は、Gopherがテスト全体がタイムアウトして出力を受信するまで待つ必要なく、テストの失敗をデバッグするのに役立ちます。