Golang: как именовать и где хранить интеграционные тесты?
В Go интеграционные тесты требуют отдельного подхода к организации и именованию, чтобы их можно было удобно запускать и поддерживать. Вот лучшие практики для именования, хранения и управления интеграционными тестами:
1. Где хранить интеграционные тесты
Интеграционные тесты могут находиться в одном из двух мест:
Внутри основного пакета (_test.go в той же директории)
Интеграционные тесты можно размещать в тех же директориях, что и код, который они проверяют, но с некоторыми отличиями:
- Файлы с тестами должны оканчиваться на _test.go.
- Тесты интеграционного уровня можно отделять от юнит-тестов, создавая файлы с именами вроде integration_test.go.
Пример структуры:
| 1 2 3 4 5 6 7 8 | project/ ├── pkg/ │   ├── module/ │   │   ├── module.go │   │   ├── module_test.go           # Юнит-тесты │   │   ├── integration_test.go      # Интеграционные тесты ├── main.go | 
В отдельной директории (например, /test или /integration)
Если интеграционные тесты требуют настройки инфраструктуры или запуска зависимостей (например, базы данных, Kafka или REST API), лучше выделить их в отдельную директорию.
Пример структуры:
| 1 2 3 4 5 6 7 8 9 10 11 | project/ ├── pkg/ │   ├── module/ │   │   ├── module.go │   │   ├── module_test.go          # Юнит-тесты ├── test/ │   ├── integration/ │   │   ├── kafka_integration_test.go │   │   ├── database_integration_test.go │   ├── docker-compose.yml          # Настройки для инфраструктуры | 
2. Как именовать интеграционные тесты
Файлы
- Убедитесь, что файлы заканчиваются на _test.go, чтобы Go их распознал как тестовые.
- Включите слово integrationв имя файла, чтобы отличить интеграционные тесты от юнит-тестов.- Примеры:
- kafka_integration_test.go
- database_integration_test.go
 
 
- Примеры:
Тестовые функции
- Используйте префикс Test(требование Go), а затем описывайте сценарий.
- Можно добавлять Integrationв название функции, чтобы явно указать её цель:- Примеры:
- func TestIntegrationKafkaConsumer(t *testing.T)
- func TestDatabaseIntegration(t *testing.T)
 
 
- Примеры:
3. Как запускать интеграционные тесты
| 1 2 3 4 5 6 7 8 9 10 11 | //go:build integration // +build integration package main import "testing" func TestIntegrationExample(t *testing.T) {     t.Log("Интеграционный тест") } | 
Запуск:
| 1 2 | go test -tags=integration ./... | 
Разделить запуск по пакетам: Например, запускать только тесты в директории test/integration:
| 1 2 | go test ./test/integration/... | 
Использовать окружения: Используйте переменные окружения для указания, что вы запускаете интеграционные тесты:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import (     "os"     "testing" ) func TestIntegrationExample(t *testing.T) {     if os.Getenv("RUN_INTEGRATION_TESTS") != "true" {         t.Skip("Пропускаем интеграционные тесты")     }     t.Log("Интеграционный тест выполняется") } | 
Запуск:
| 1 2 | RUN_INTEGRATION_TESTS=true go test ./... | 
4. Как организовать зависимости для интеграционных тестов
Интеграционные тесты часто требуют запуска сторонних сервисов (например, Kafka, базы данных). Вот подходы для их настройки:
Локальная инфраструктура
- Используйте docker-composeдля запуска зависимостей:- Пример docker-compose.ymlдля Kafka:
 123456789101112131415161718version: '3.8'services:zookeeper:image: confluentinc/cp-zookeeper:latestports:- "2181:2181"environment:ZOOKEEPER_CLIENT_PORT: 2181kafka:image: confluentinc/cp-kafka:latestports:- "9092:9092"environment:KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181KAFKA_LISTENERS: PLAINTEXT://:9092KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092KAFKA_BROKER_ID: 1
 
- Пример 
Эмуляторы и mock-объекты
- Используйте библиотеки вроде Sarama mocks для имитации Kafka.
- Для баз данных можно использовать in-memory базы данных, такие как SQLite.
5. Лучшие практики для интеграционных тестов
- Изолированность:
- Тесты не должны зависеть от данных, оставленных другими тестами.
- Убедитесь, что перед тестами очищается состояние (например, очищаются базы данных или Kafka-топики).
 
- Идентификация зависимостей:
- Чётко укажите, какие сервисы необходимы для выполнения теста (например, через docker-composeили в документации).
 
- Чётко укажите, какие сервисы необходимы для выполнения теста (например, через 
- Логирование:
- Логируйте важные шаги интеграционных тестов, чтобы упростить отладку.
 
- Запуск в CI/CD:
- Настройте запуск интеграционных тестов в CI/CD, добавив зависимости как сервисы (например, через Docker).
 
- Оптимизация времени выполнения:
- Группируйте тесты, чтобы минимизировать запуск зависимостей.
 
Итог:
- Именование: используйте _test.goи добавляйтеintegrationв имя файла и функций.
- Хранение: либо рядом с основным кодом (integration_test.go), либо в отдельной директории (/test/integration).
- Запуск: используйте теги, переменные окружения или разделяйте тесты по пакетам.
- Зависимости: автоматизируйте с помощью Docker или эмуляторов.
Следуя этим рекомендациям, вы сделаете интеграционные тесты читаемыми, простыми в запуске и удобными для сопровождения.
Recommended Posts
Golang map и Swiss Table
16.03.2025
