Ответ
В Go для тестирования используется встроенный пакет testing
и стандартная утилита go test
. Мой подход к тестированию включает несколько ключевых практик:
-
Unit-тесты (Модульные тесты): Тестирование отдельных, изолированных частей кода (функций, методов). Это основа пирамиды тестирования.
-
Table-driven тесты (Табличные тесты): Идеальный способ для проверки функции с множеством различных входных данных и ожидаемых результатов. Это делает тесты компактными и легко расширяемыми.
func TestMultiply(t *testing.T) { testCases := []struct { name string a, b int want int }{ {"positive numbers", 2, 3, 6}, {"multiplication by zero", 0, 5, 0}, {"negative number", -2, 4, -8}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { got := Multiply(tc.a, tc.b) if got != tc.want { t.Errorf("Multiply(%d, %d) = %d; want %d", tc.a, tc.b, got, tc.want) } }) } }
-
Интеграционные тесты: Проверяют взаимодействие нескольких компонентов системы (например, сервис и база данных). Для их отделения от быстрых unit-тестов я использую билд-теги.
- Файл теста помечается комментарием:
//go:build integration
- Запуск производится отдельной командой:
go test -v -tags=integration
- Файл теста помечается комментарием:
-
Моки и Стабы (Mocks & Stubs): Для изоляции тестируемого компонента от его зависимостей (БД, внешние API) я использую моки. Это позволяет тестировать логику компонента, не затрагивая внешние системы. Популярные библиотеки:
testify/mock
иgomock
. -
Бенчмарки (Benchmarks): Для измерения производительности критически важных участков кода. Используется
testing.B
.func BenchmarkMultiply(b *testing.B) { for i := 0; i < b.N; i++ { Multiply(1024, 1024) } }
-
Вспомогательные библиотеки: Часто использую
testify/assert
иtestify/require
для более читаемых и удобных проверок вместо стандартныхif got != want
.