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

Курсы

Программирование
Unity Game Developer. Basic
-15%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
Разработчик C#
-8%
Алгоритмы и структуры данных
-8%
Backend-разработчик на PHP
-8%
JavaScript Developer. Professional
-9%
iOS Developer. Professional
-8%
Базы данных
-12%
C# ASP.NET Core разработчик
-6%
Python Developer. Basic
-10%
Java Developer. Professional Web-разработчик на Python Android Developer. Basic PostgreSQL Software Architect Reverse-Engineering. Professional Kotlin Backend Developer React.js Developer VOIP инженер Нереляционные базы данных Scala-разработчик Супер-практикум по использованию и настройке GIT IoT-разработчик JavaScript Developer. Basic Advanced Fullstack JavaScript developer Unity Game Developer. Professional Супер-интенсив Azure
Инфраструктура
Супер-интенсив "Версионирование и командная работа с помощью Git"
-30%
Administrator Linux. Professional
-5%
Супер-интенсив «CI/CD или Непрерывная поставка с Docker и Kubernetes»
-30%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-6%
Administrator Linux. Advanced
-8%
Infrastructure as a code in Ansible
-12%
Network engineer
-4%
MS SQL Server Developer
-8%
Cloud Solution Architecture Highload Architect Разработчик голосовых ассистентов и чат-ботов Мониторинг и логирование: Zabbix, Prometheus, ELK Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Архитектор сетей Супер-интенсив «IaC Ansible»
Специализации Курсы в разработке Подготовительные курсы
+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 комментарий
Комментарий удален
Для комментирования необходимо авторизоваться