t.Log()
не будет отображаться до тех пор, пока тест не будет завершен, поэтому, если вы пытаетесь отладить тест, который зависает или работает плохо, вам кажется, что вам нужно использовать fmt
.
Да: так было до версии Go 1.13 (август 2019 г.) включительно.
За этим последовал 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 также завершают тесты, если нет вывод журнала через определенное время (например, 10 минут в CircleCI).
Итак, теперь мои тесты убиты, и у меня нет ничего в журналах, чтобы рассказать мне, что произошло.
Но для (возможно) Go 1.14 ( первый квартал 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
Это действительно в Go 1.14, как утверждает Дэйв Чейни в « go test -v
потоковом выводе »:
В Go 1.14 выводится go test -v
потоком по мере его поступления, а не накапливается до конца тестового прогона .t.Log
Под Go 1.14 fmt.Println
и t.Log
линии перемежаются , а не ждать окончания тестирования, демонстрации того, что тестовый выход в потоковом режиме, когда go test -v
используется.
Преимущество, по словам Дэйва:
Это большое улучшение качества жизни для тестов стиля интеграции, которые часто повторяются в течение длительного времени, когда тест не работает.
Потоковый t.Log
вывод поможет Gophers отлаживать эти сбои теста, не дожидаясь, пока истечет время всего теста, чтобы получить их результат.