Перейти к основному содержимому

Практика: Тестирование


Онлайн редактор кода для Go

Здесь вы можете попробовать свои силы в программировании на языке Go. Для этого мы предоставляем вам онлайн редактор кода, в котором вы можете написать свой код и запустить его.

❗️ При обновлении страницы код пропадёт, по этому, сохраните свой код куда-нибудь, если он важный.

Задание 1: Тесты для математического калькулятора

Задание 1: Табличные тесты для Add

Напиши функцию Add(a, b int) int. Создай таблицу из 8–10 тестовых случаев (положительные, отрицательные, нули, большие числа). Используй t.Run для подтестов с понятными именами.


💡 Подсказка

Используй структуру с полями name, a, b, expected.

t.Run(test.name, func(t *testing.T) { ... })

t.Errorf с понятным сообщением: got %d, want %d

Запусти go test -v для красивого вывода подтестов.

Задание 2: Тесты с ошибками для SafeDivide

Задание 2: Тесты с ошибками для деления

Напиши функцию SafeDivide(a, b float64) (float64, error) с проверкой деления на ноль. Создай таблицу тестов: успешные случаи и случаи с ошибкой.


💡 Подсказка

В успешных случаях проверяй err == nil и result == expected.

В ошибочных — err != nil и можно проверить сообщение.

Для float64 используй точное сравнение (для простых случаев) или math.Abs(result-expected) < 1e-9.

t.Run для каждого случая.

Задание 3: Two Sum — LeetCode 1 (связь с темой)

Задание 3: Two Sum — поиск пары (LeetCode 1)

Дан слайс nums и target. Верни индексы двух чисел, сумма которых равна target. Эта задача идеально подходит для написания табличных тестов с разными входными данными.


💡 Подсказка

Эта задача — отличный пример для табличных тестов: много разных входов, один ожидаемый результат.

Решение: map[int]int для хранения индексов.

В тестах проверяй, что возвращённые индексы дают правильную сумму.

Порядок индексов не важен — сортируй и сравнивай.

Задание 4: Бенчмарки конкатенации строк

Задание 4: Бенчмарки + vs strings.Builder

Напиши два бенчмарка: один с конкатенацией через +=, второй с strings.Builder. Сравни производительность и аллокации для цикла из N итераций.


💡 Подсказка

func BenchmarkConcatPlus(b *testing.B) { ... }

b.ResetTimer() перед циклом.

b.ReportAllocs() для показа аллокаций.

Запусти go test -bench=. -benchmem

Задание 5: Тест на гонку данных в счётчике

Задание 5: SafeCounter и race detector

Создай структуру SafeCounter с полем value и методом Increment(). Сначала реализуй без мьютекса — запусти тест с горутинами и go test -race. Потом добавь sync.Mutex и покажи, что гонка исчезла.


💡 Подсказка

sync.WaitGroup для ожидания всех горутин.

В тесте запусти N горутин, каждая делает M инкрементов.

go test -race покажет data race без мьютекса.

С мьютексом — значение должно быть точно N*M.

Задание 6: Palindrome Number — LeetCode 9 (связь с темой)

Задание 6: Palindrome Number — проверка палиндрома (LeetCode 9)

Дано целое число x. Верни true, если оно палиндром. Эта задача отлично подходит для табличных тестов с разными входными числами и ожидаемыми результатами.


💡 Подсказка

Эта задача — отличный кейс для табличных тестов: много разных чисел, простой ожидаемый результат.

Решение: преобразование в строку или математическое разворачивание.

Отрицательные сразу false.

Обрабатывай переполнение при разворачивании.

Задание 7: Тестовые хелперы

Задание 7: Собственные хелперы для тестов

Создай файл test_helpers.go с функциями AssertEqual, AssertNoError, AssertError (все с t.Helper()). Перепиши тесты из предыдущих заданий с использованием хелперов.


💡 Подсказка

t.Helper() — обязательно, чтобы ошибка показывала строку вызова, а не хелпера.

interface для универсальности (или дженерики в Go 1.18+).

reflect.DeepEqual для сложных типов.

Перепиши старые тесты — вывод станет чище.

Пример хелперов

  • AssertContains(t *testing.T, s, substr string) — проверяет, что строка содержит подстроку
  • AssertNil(t *testing.T, v interface) и AssertNotNil(t *testing.T, v interface) — проверяет, nil или не nil
  • AssertSliceEqual(t *testing.T, got, want []int) — сравнение слайсов
  • AssertApproxEqual(t *testing.T, got, want, delta float64) — для float с погрешностью

Дополнительные материалы

  • Покрытие кода: go test -coverprofile и go tool cover
  • Таблица тестов с t.Parallel() для ускорения
  • golden files для тестирования вывода
  • testify/assert для продвинутых ассертов
Совет

Пиши тесты сразу с функцией — это TDD (Test-Driven Development). Хорошие тесты — это документация и защита от регрессий!

Следующий урок

Продвинутые темы: контекст, рефлексия, генерация кода.