go test: пакеты, cache, race, count и run
go test компилирует пакет и исполняет его tests, examples и fuzz targets согласно выбранным флагам. ./... рекурсивно выбирает пакеты текущего модуля, но не заменяет явно спланированные integration- или e2e-проверки.
Зачем это на интервью
Важно показать, как из «тест зелёный локально» получить воспроизводимое доказательство: выбрать пакет, отключить cache при диагностике, повторить flaky case и проверить конкурентный путь.
Минимум для E4
- Запускать всё:
go test ./...; один пакет:go test ./internal/auth. - Фильтровать полным regexp:
go test ./... -run '^TestLogin$'. - Повторять без cache:
go test ./... -count=1; ловить flaky:-count=100. - Запускать race detector:
go test -race ./....
go test ./...
go test ./internal/cache -run '^TestStore/(miss|hit)$' -count=1 -v
go test -race ./internal/cache -count=20
go test ./... -shuffle=onУглубление для E5/Senior
Cache ускоряет успешные package tests и зависит от исходников, окружения и флагов. Не обвиняйте cache без проверки -count=1; напротив, не выключайте его постоянно в обычном feedback loop. -run применяет regexp к имени теста и subtest; якоря не дают случайно запустить похожие тесты. -count повторяет тестовый binary; -shuffle=on помогает обнаружить зависимость от порядка.
Race detector инструментирует memory accesses и сообщает о наблюдённых data races. Он существенно медленнее и требует выполнения конфликтующего schedule; чистый прогон не является математическим доказательством. В CI полезны -race на поддерживаемой платформе и тесты, которые реально создают конкуренцию. Исправление — синхронизация/владение данными, не time.Sleep.
Ключевые понятия
| Флаг | Назначение |
|---|---|
./... | пакеты под текущим модулем |
-run re | отбор Test/Benchmark/Fuzz по regexp |
-count=n | повторение, 1 отключает test cache |
-race | обнаружение выполненных data races |
-shuffle | изменение порядка тестов и subtests |
Типовые вопросы
- Почему
-count=1полезен? — Исключает использование test cache при проверке воспроизводимости. - Почему
-run TestXрискован? — Это regexp; без^...$могут совпасть другие имена. - Находит ли
-raceвсе гонки? — Нет, только гонки на реально выполненных путях и interleavings. - Нужно ли всегда тестировать
./...? — Перед merge обычно да; в цикле разработки узкий пакет быстрее, но не заменяет полный gate. - Как расследовать flaky test? — Зафиксировать seed/окружение, повторить
-count, включить-shuffle, убрать зависимости от времени и глобального состояния.
Практика
- Напишите тест с subtests и запустите ровно один. Готово: команда с якорным
-runзапускает ожидаемое имя и только его. - Внесите намеренную race в счётчик. Готово:
-raceсообщает конфликт, а исправление mutex/atomic проходит-count=50.
Частые ошибки и ловушки
- Интерпретировать cache hit как отсутствие исполнения теста при расследовании.
- Считать
-raceповодом не проектировать ownership данных. - Прятать flaky test за retry вместо устранения причины.
Связанные темы
Инструменты Go · Тестирование · Конкурентность Go