Несколько слов о запуске Go-тестов
Рассмотрим в качестве примера простой проект на Go, его структура описана ниже:
example ├── cmd │ └── main.go ├── go.mod ├── go.sum └── pkg ├── bar │ ├── bar.go │ └── bar_test.go └── foo ├── foo.go └── foo_test.go 4 directories, 7 files
Заметим, что в пакетах foo и bar присутствуют тесты, попробуем запустить их из корня командой go test ./...:
? example/cmd [no test files] ok example/pkg/bar 0.006s ok example/pkg/foo 0.005s
В процессе работы go test ./...рекурсивно обходит нашу папку и запускает все тесты, которые найдет. Это особенно удобно при использовании с CI — нам нужно добавить лишь одну строку в конфигурацию.
Может показаться, что тесты выполняются последовательно, друг за другом. При использовании дефолтных настроек это не так. Проверим — внесем следующие изменения в код:
func TestNewBar(t *testing.T) { log.Printf("bar test start time: %v", time.Now()) time.Sleep(time.Second) bar := NewBar(100) require.Equal(t, 101, bar.Size) } func TestNewFoo(t *testing.T) { log.Printf("foo test start time: %v", time.Now()) time.Sleep(time.Second) foo := NewFoo(100) require.Equal(t, 101, foo.Size) }
Для каждого теста мы добавили печать времени запуска, задержку в секунду и плюс сделали так, чтобы они гарантированно не проходили. Повторим запуск:
? example/cmd [no test files] 2020/07/18 12:50:54 bar test start time: 2020-07-18 12:50:54.079533681 +0700 +07 m=+0.001231839 --- FAIL: TestNewBar (1.00s) bar_test.go:15: Error Trace: bar_test.go:15 Error: Not equal: expected: 101 actual : 100 Test: TestNewBar FAIL FAIL example/pkg/bar 1.006s 2020/07/18 12:50:54 foo test start time: 2020-07-18 12:50:54.079717636 +0700 +07 m=+0.001206226 --- FAIL: TestNewFoo (1.00s) foo_test.go:15: Error Trace: foo_test.go:15 Error: Not equal: expected: 101 actual : 100 Test: TestNewFoo FAIL FAIL example/pkg/foo 1.005s FAIL
Обратите внимание на времена, которые мы логируем — они практически одинаковые, что подтверждает нашу теорию.
На данном примере хотелось показать, что запуск тестов таким образом может выполняться не так, как вы ожидали. Это особенно актуально для сложных тестов (например интеграционных), где есть общее состояние (например база данных) — параллельный запуск может стать неожиданным сюрпризом в получаемых результатах.
Для особенно заинтересовавшихся темой оставляю ссылку на исходных код запуска тестов, в котором можно найти все детали: [https://golang.org/src/cmd/go/internal/work/exec.go?s=981:1015#L46](https://golang.org/src/cmd/go/internal/work/exec.go?s=981:1015#L46).