Какие подходы и инструменты используются для написания интеграционных тестов в Go?

Ответ

Интеграционные тесты проверяют взаимодействие между несколькими компонентами системы (например, сервис и база данных). В Go для этого используются следующие подходы и инструменты:

1. Тестирование HTTP-слоя с net/http/httptest

Стандартная библиотека предоставляет пакет httptest для тестирования HTTP-хендлеров без реального запуска сервера. Он позволяет создавать моки запросов (NewRequest) и записывать ответы (NewRecorder).

Пример:

func TestGetUserHandler(t *testing.T) {
    // Создаем мок-запрос к нашему хендлеру
    req := httptest.NewRequest(http.MethodGet, "/users/1", nil)
    w := httptest.NewRecorder()

    // Предположим, что GetUserHandler - это наш http.Handler
    GetUserHandler(w, req)

    // Проверяем статус-код ответа
    if w.Code != http.StatusOK {
        t.Errorf("Expected status OK; got %v", w.Code)
    }

    // Проверяем тело ответа
    var user User
    if err := json.NewDecoder(w.Body).Decode(&user); err != nil {
        t.Fatalf("Could not decode response: %v", err)
    }

    if user.ID != 1 {
        t.Errorf("Expected user ID 1; got %d", user.ID)
    }
}

2. Работа с внешними зависимостями (БД, кэши)

Для интеграционных тестов с базами данных (PostgreSQL, MySQL) или кэшами (Redis) лучшей практикой является запуск этих зависимостей в Docker-контейнерах на время теста. Это гарантирует чистое и изолированное окружение.

  • Инструменты: Библиотека testcontainers-go сильно упрощает управление жизненным циклом Docker-контейнеров прямо из Go-кода.

3. Разделение тестов с помощью Build Tags

Интеграционные тесты обычно медленнее юнит-тестов, поэтому их часто запускают отдельно. Для этого используются build-теги.

  1. В начало файла с интеграционным тестом добавляется специальный комментарий:

    //go:build integration
    
    package my_test
  2. Запуск тестов выполняется с указанием тега:

    # Запустить только интеграционные тесты
    go test -v -tags=integration ./...
    
    # Запустить все тесты, кроме интеграционных
    go test -v ./...