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
Что такое oneof в Protobuf?
25.04.2024