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).
Тож зараз мої тести вбиваються, і я не маю нічого в журналах, щоб сказати, що сталося.
Але для (можливо) переходу 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
Це дійсно в 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 налагоджувати ці тестові збої без необхідності чекати, поки не будуть випробовані всі тестові рази, щоб отримати їх вихід.