Несколько слов о запуске Go-тестов | OTUS
⚡ Открываем подписку на курсы!
Проходите параллельно 3 онлайн-курса в месяц по цене одного.
Подробнее

Курсы

Программирование
Flutter Mobile Developer Подготовка к сертификации Oracle Java Programmer (OCAJP)
-8%
Алгоритмы и структуры данных
-12%
Web-разработчик на Python
-11%
Архитектура и шаблоны проектирования
-14%
JavaScript Developer. Basic Супер-интенсив «СУБД в высоконагруженных системах»
-18%
iOS-разработчик. Базовый курс
-23%
Разработчик на Spring Framework
-23%
Python Developer. Basic
-16%
C# ASP.NET Core разработчик
-18%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
Android Developer. Basic
-10%
C++ Developer. Professional Разработчик C# AWS для разработчиков Software Architect Unity Game Developer. Basic Разработчик голосовых ассистентов и чат-ботов Backend-разработка на Kotlin React.js Developer Разработчик Node.js Нереляционные базы данных Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Advanced Fullstack JavaScript developer
Инфраструктура
PostgreSQL
-10%
IoT-разработчик
-12%
Administrator Linux. Professional
-11%
Базы данных
-19%
Administrator Linux.Basic
-18%
Супер-интенсив «СУБД в высоконагруженных системах»
-18%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
Сетевой инженер AWS для разработчиков Software Architect Reverse-Engineering. Professional CI/CD VOIP инженер Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Несколько слов о запуске 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.

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
1 комментарий
Комментарий удален
Для комментирования необходимо авторизоваться