Как устроена автоматизация тестов и интеграционное тестирование
Что проверяют
Умеете ли вы отделить юнит-тесты от интеграционных и поднять для вторых реальное окружение, а не имитацию. Следом обычно спрашивают, как вы тестируете код, работающий с базой, и как интеграционные тесты запускаются в CI.
Как отвечать
Основа это стандартный пакет testing и команда go test, отдельный фреймворк не нужен:
- табличные тесты: срез кейсов и
t.Runна каждый, так тест легко расширять, а падает он с понятным именем подтеста. Независимые кейсы помечаютсяt.Parallel(); - ассерты:
testifyудобен, но разницу важно знать:requireостанавливает тест при ошибке,assertпродолжает; - изоляция в юнит-тестах: зависимости принимаются интерфейсами, в тестах подставляются фейки, написанные руками, или моки из
go.uber.org/mockиmockery; - HTTP:
httptest.NewRecorderдля проверки хендлера,httptest.NewServerвместо внешнего API; - интеграционные тесты: реальные PostgreSQL, Kafka или Redis в Docker через testcontainers-go, контейнер поднимается в
TestMainи гасится после прогона. Миграции накатываются тем же инструментом, что и в проде; - разделение: интеграционные тесты помечаются build-тегом
//go:build integrationи запускаются черезgo test -tags=integration ./..., либо пропускаются поtesting.Short(); - CI: юнит-тесты с
-raceи покрытием на каждый merge request, интеграционные отдельной джобой с Docker.
Уборку после теста регистрируйте через t.Cleanup, а данные между тестами изолируйте транзакцией с откатом или отдельной схемой на тест.
Подкрепите ответ примером из опыта: какой баг поймал именно интеграционный тест, например неверный SQL или несовпадение типов в драйвере.
Где спотыкаются
Называют интеграционным тестом вызов настоящего стороннего API. Такой тест падает от чужой нестабильности и лимитов, поэтому внешний сервис заменяют httptest-сервером или контрактными тестами.
Забывают про кеш go test: успешный результат кешируется, и тест против внешней базы может вообще не запуститься. Для таких прогонов добавляют -count=1.
Мокают базу в тестах репозитория. Мок подтверждает, что вызван нужный метод, но не проверяет сам SQL, ради которого этот слой и тестируют.