Тестирование в Go
Тестирование в Go
Пакет testing в стандартной библиотеке — основа. Идиоматичный стиль — table-driven tests. Для HTTP — net/http/httptest, для удобных assert — testify.
База: Первая программа на Go · Справочник по Go · Фреймворки.
Именование и запуск
Файл: greeting_test.go в том же пакете, что и код.
package greeting
import "testing"
func TestHello(t *testing.T) {
got := Hello("Go")
want := "Hello, Go!"
if got != want {
t.Errorf("Hello() = %q, want %q", got, want)
}
}
go test ./...
go test -v ./pkg/greeting
go test -cover ./...
Table-driven tests
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
want int
}{
{"zeros", 0, 0, 0},
{"positive", 2, 3, 5},
{"negative", -1, 1, 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("got %d, want %d", got, tt.want)
}
})
}
}
t.Run даёт изолированные подтесты в отчёте.
testify
go get github.com/stretchr/testify
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestHelloAssert(t *testing.T) {
assert.Equal(t, "Hi, Ann", Hello("Ann"))
require.NotEmpty(t, Hello("x")) // require останавливает тест при провале
}
HTTP handler (httptest)
func TestHealthHandler(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/health", nil)
rec := httptest.NewRecorder()
HealthHandler(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
assert.Contains(t, rec.Body.String(), "ok")
}
Для Gin: router := gin.New(); router.ServeHTTP(rec, req).
Моки интерфейсов
Go не имеет встроенных моков — используют интерфейсы и ручные fake:
type UserStore interface {
Save(name string) error
}
type fakeStore struct {
saved []string
}
func (f *fakeStore) Save(name string) error {
f.saved = append(f.saved, name)
return nil
}
func TestService_Register(t *testing.T) {
store := &fakeStore{}
svc := NewService(store)
require.NoError(t, svc.Register("Ann"))
assert.Equal(t, []string{"Ann"}, store.saved)
}
Генераторы: mockgen (gomock), moq — для крупных проектов.
Benchmark
func BenchmarkHello(b *testing.B) {
for i := 0; i < b.N; i++ {
Hello("bench")
}
}
go test -bench=. -benchmem ./...
CI
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- run: go test -race -coverprofile=coverage.out ./...
Флаг -race включает детектор гонок данных.
Связанные материалы
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). Основы языка Go - философия простоты, модель компиляции и идиоматичный подход к системной разработке. Фундамент для начинающего программиста - что повторить, как работать, чего ожидать. Набор советов, правил, принципов и обычаев в разработке на этом языке. История Go - инженерные цели языка, философия простоты и эволюция инструментов экосистемы. Экосистема приложений на Go - встроенные инструменты, workflow разработки и практики сопровождения проектов. Кавычки, rune и string, точка, запятая, автоматическая вставка точки с запятой, скобки, подчёркивания и типичные ошибки новичков в Go. Предопределённые идентификаторы не являются ключевыми словами, но имеют специальное значение в языке. Их можно переопределить в локальной области видимости, но делать это не рекомендуется. Набор функций, которые включены в стандартную библиотеку языка. Особенности Go - интерфейсы, композиция, модель ошибок и практики написания поддерживаемого кода. Go вводит конкурентность через встроенные синтаксические конструкции и правила выполнения. Ниже рассматриваются основные направления практического применения Go, объяснённые через призму его технических характеристик и требований реальных инфраструктур. Типизация, набор правил определения типа данных значений языка.Основы языка Go
Что требуется знать перед началом изучения языка программирования Go
Рекомендации по разработке на Go
История языка Go
Экосистема приложений на Go
Синтаксис и пунктуация в Go
Ключевые слова языка Go
Встроенные функции и пакеты Go
Особенности языка Go
Синтаксические конструкции Go
Области применения Go
Типы данных и объявление переменных в Go