Тестирование в Go (Golang): фреймворки и инструменты
Go (Golang) — один из немногих языков, где тестирование заложено на уровне стандартной библиотеки. Благодаря встроенному пакету testing, а также мощным сторонним инструментам, разработчики могут строить надёжные и производительные приложения. В этой статье мы разберём основные фреймворки и утилиты для тестирования кода на Go: от простых юнит-тестов до моков и проверки утечек горутин.
Встроенный пакет testing
Пакет testing — основа всего тестирования в Go. Тесты пишутся в файлах с суффиксом _test.go. Функции тестов должны иметь сигнатуру func TestXxx(t *testing.T). Запуск — командой go test.
package main
import (
"testing"
)
func Sum(a, b int) int {
return a + b
}
func TestSum(t *testing.T) {
result := Sum(2, 3)
expected := 5
if result != expected {
t.Errorf("Sum(2,3) = %d; want %d", result, expected)
}
}
Для табличных тестов используется слайс структур:
func TestSumTable(t *testing.T) {
tests := []struct {
a, b, expected int
}{
{1, 2, 3},
{0, 0, 0},
{-1, 1, 0},
}
for _, tt := range tests {
result := Sum(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Sum(%d,%d) = %d; want %d", tt.a, tt.b, result, tt.expected)
}
}
}
Также поддерживаются:
- Бенчмарки — функции
func BenchmarkXxx(b *testing.B), запускаются черезgo test -bench=. - Примеры — функции
func ExampleXxx()для генерации документации и проверки вывода. - Подтесты —
t.Run("name", func(t *testing.T) {...})для группировки и параллельного выполнения.
Testify — расширение возможностей
Testify — самый популярный фреймворк для тестирования в Go. Он добавляет удобные ассерты, моки и набор утилит.
Основные пакеты Testify:
assert— проверки с понятными сообщениями об ошибках.require— как assert, но прерывает тест при неудаче.mock— создание и проверка мок-объектов.suite— группировка тестов в классы (TDD-стиль).
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
// Пример использования assert
func TestSumWithTestify(t *testing.T) {
assert.Equal(t, 5, Sum(2, 3))
assert.NotEqual(t, 0, Sum(-1, 1))
}
// Пример мока с testify/mock
type Calculator interface {
Add(a, b int) int
}
type MockCalculator struct {
mock.Mock
}
func (m *MockCalculator) Add(a, b int) int {
args := m.Called(a, b)
return args.Int(0)
}
func TestWithMock(t *testing.T) {
mockCalc := new(MockCalculator)
mockCalc.On("Add", 2, 3).Return(5)
result := mockCalc.Add(2, 3)
assert.Equal(t, 5, result)
mockCalc.AssertExpectations(t)
}
Gomock — генерация моков из интерфейсов
Gomock (форк оригинального от Google) — инструмент для автоматической генерации моков на основе интерфейсов. Используется совместно с утилитой mockgen.
Установка и базовый пример:
// Установка
go install go.uber.org/mock/mockgen@latest
// Генерация мока для интерфейса
// mockgen -source=calculator.go -destination=mock_calculator.go -package=main
// Использование в тесте
func TestWithGomock(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockCalc := NewMockCalculator(ctrl)
mockCalc.EXPECT().Add(2, 3).Return(5)
result := mockCalc.Add(2, 3)
if result != 5 {
t.Errorf("Expected 5, got %d", result)
}
}
Gomock поддерживает:
- Указание