Ответ
Тестирование в Go является первоклассной возможностью языка и встроено в стандартный инструментарий. Для этого используется пакет testing
и команда go test
.
Основные принципы:
- Тесты находятся в файлах с суффиксом
_test.go
в том же пакете, что и тестируемый код. - Команда
go test
автоматически находит и запускает такие файлы.
Основные виды тестов:
-
Юнит-тесты (Unit Tests)
- Функция должна начинаться с
Test
, например,TestMyFunction
. - Принимает один аргумент:
t *testing.T
. - С помощью
t
можно сообщать об ошибках (t.Error
,t.Errorf
), прерывать тест (t.Fatal
,t.Fatalf
) или организовывать под-тесты (t.Run
).// main.go func Add(a, b int) int { return a + b }
// main_test.go func TestAdd(t *testing.T) { // Популярный подход "table-driven tests" testCases := []struct{ a, b, expected int }{ {1, 2, 3}, {0, 0, 0}, {-1, 1, 0}, }
for _, tc := range testCases { t.Run("test case", func(t *testing.T) { if result := Add(tc.a, tc.b); result != tc.expected { t.Errorf("Add(%d, %d) = %d; want %d", tc.a, tc.b, result, tc.expected) } }) }
}
- Функция должна начинаться с
-
Бенчмарки (Benchmark Tests)
- Функция начинается с
Benchmark
, например,BenchmarkMyFunction
. - Принимает
b *testing.B
. - Код, производительность которого измеряется, помещается в цикл
for i := 0; i < b.N; i++
. - Запускаются командой
go test -bench=.
.
- Функция начинается с
-
Тесты-примеры (Example Tests)
- Функция начинается с
Example
, например,ExampleMyFunction
. - Используются для документации: их код отображается в godoc. Они также являются исполняемыми тестами: Go проверяет, что вывод в
stdout
соответствует комментарию// Output:
.
- Функция начинается с
-
Фаззинг-тесты (Fuzzing)
- Добавлены в Go 1.18. Предназначены для поиска неожиданных багов путем подачи в функцию случайных входных данных.
- Функция начинается с
Fuzz
, например,FuzzMyFunction
. - Принимает
f *testing.F
.
Полезные команды и флаги:
go test
: запустить все тесты в текущем пакете.go test ./...
: запустить тесты во всех под-пакетах.go test -v
: показать детальный вывод, включая имена тестов.go test -cover
: показать процент покрытия кода тестами.go test -run TestName
: запустить конкретный тест по имени (регулярное выражение).t.Parallel()
: позволяет запускать тесты (или под-тесты) параллельно, что ускоряет выполнение.