Go предоставляет встроенный пакет testing для написания тестов. Вот как им пользоваться:
// math.go
package math
func Add(a, b int) int {
return a + b
}
// math_test.go
package math
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2, 3) = %d; want 5", result)
}
}
Идеальный подход для большинства случаев:
func TestAdd_TDD(t *testing.T) {
tests := []struct {
name string
a, b int
want int
}{
{"positive", 2, 3, 5},
{"negative", -1, -1, -2},
{"zero", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Add(tt.a, tt.b); got != tt.want {
t.Errorf("Add() = %v, want %v", got, tt.want)
}
})
}
}
t.Error() / t.Errorf() - сообщение об ошибке без остановки тестаt.Fatal() / t.Fatalf() - критическая ошибка, прерывающая тестt.Log() - вывод дополнительной информацииt.Helper() - пометка функции как вспомогательнойt.Parallel() - запуск теста параллельноНаиболее популярный набор инструментов:
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
// Простые assertions
func TestAdd_Testify(t *testing.T) {
result := Add(2, 3)
assert.Equal(t, 5, result, "they should be equal")
require.NotNil(t, result, "result should not be nil")
}
// Test suites
type MathTestSuite struct {
suite.Suite
}
func (s *MathTestSuite) TestAdd() {
s.Equal(5, Add(2, 3))
}
func TestMathSuite(t *testing.T) {
suite.Run(t, new(MathTestSuite))
}
Преимущества Testify:
mock)Генерация моков на основе интерфейсов:
go install github.com/golang/mock/mockgen@latest
mockgen -source=repository.go -destination=repository_mock.go -package=mocks
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRepo := mocks.NewMockRepository(ctrl)
mockRepo.EXPECT().
FindByID(123).
Return(&User{Name: "John"}, nil)
Именование:
*_test.goTest[Функция]_[Сценарий] или Test[Функция]tt (test case), want (ожидаемое значение)Организация:
internal/testutils для вспомогательных функцийПокрытие:
go test -covergo test -coverprofile=coverage.out && go tool cover -html=coverage.outПараллелизация:
func TestParallel(t *testing.T) {
t.Parallel()
// тестовый код
}
Go предлагает:
testing для unit-тестовВыбор инструментов зависит от проекта: