t.Log()
直到测试完成后才会显示,因此,如果您要调试挂起或性能不佳的测试,似乎需要使用fmt
。
是的:包括Go 1.13(2019年8月)就是这种情况。
随后是golang.org
问题24929
考虑以下(愚蠢的)自动化测试:
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(Q1 2020):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
正如Dave Cheney在“ go test -v
流输出 ”中所证明的,它确实在Go 1.14中:
在Go 1.14中,go test -v
将在发生流时t.Log
输出流,而不是在测试运行结束之前将其存储起来。
在Go 1.14中,fmt.Println
和t.Log
行是交错的,而不是等待测试完成,这表明go test -v
使用时将流式传输测试输出。
根据Dave的优势:
对于集成样式测试,这可以提高生活质量,当测试失败时,集成样式测试通常会长时间重试。
流式t.Log
输出将帮助Gophers调试那些测试失败,而不必等到整个测试超时才能接收它们的输出。