Ответ
Интеграционные тесты проверяют, как несколько компонентов системы работают вместе как единое целое. В отличие от юнит-тестов, которые проверяют функции в изоляции (часто с использованием моков), интеграционные тесты задействуют реальные зависимости, такие как база данных, кэш, файловая система или другие микросервисы.
Основная цель — выявить ошибки на стыках компонентов: в логике взаимодействия, форматах данных, конфигурации и сетевых вызовах.
Пример в Go: Тестирование HTTP-обработчика с реальной тестовой базой данных.
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
// Предположим, у нас есть обработчик, который зависит от базы данных
func UserHandler(db *DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Логика получения пользователя из db и ответа
w.WriteHeader(http.StatusOK)
w.Write([]byte("user_data"))
}
}
func TestUserHandler_Integration(t *testing.T) {
// 1. Настройка окружения: поднимаем тестовую БД
db, cleanup := setupTestDatabase(t) // Функция, которая создает и очищает БД
defer cleanup() // Очистка после теста
// 2. Создание экземпляра приложения с реальной зависимостью
handler := UserHandler(db)
server := httptest.NewServer(handler)
defer server.Close()
// 3. Выполнение запроса к тестовому серверу
resp, err := http.Get(server.URL + "/users/1")
assert.NoError(t, err)
// 4. Проверка результата
assert.Equal(t, http.StatusOK, resp.StatusCode)
// ... можно добавить проверки тела ответа
}
Ключевые характеристики:
- Фокус: Взаимодействие между модулями.
- Окружение: Требуют настройки реального или почти реального окружения (например, Docker-контейнеры с PostgreSQL, Redis).
- Скорость: Значительно медленнее юнит-тестов.
- Надежность: Дают большую уверенность в работоспособности системы в целом.
Ответ 18+ 🔞
А, интеграционные тесты, говоришь? Ну это ж та самая хуйня, когда ты уже не просто функцию свою там тыкаешь в изоляции, а собираешь всю эту конструкцию, как пазл, и пытаешься понять — а не развалится ли она нахуй при первом же чихе?
Основная идея — поймать все эти косяки на стыках, где один модуль другому в сраку плюет не тем форматом данных, или база данных тебе вместо "ок" возвращает "иди нахуй, таблицы нет". Ёпта, классика!
Смотри, как это выглядит на Go, когда тестируешь HTTP-обработчик, который реально лезет в базу.
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
// Допустим, у нас есть обработчик, который с базой данных шашничает
func UserHandler(db *DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Тут он из базы юзера тянет и отвечает
w.WriteHeader(http.StatusOK)
w.Write([]byte("user_data"))
}
}
func TestUserHandler_Integration(t *testing.T) {
// 1. Разводим тут целую оперцию: поднимаем тестовую БД
db, cleanup := setupTestDatabase(t) // Функция, которая базу создаёт и потом прибирает за собой
defer cleanup() // Чтобы после теста не осталось следов, как после пьянки
// 2. Собираем наше детище с реальной зависимостью
handler := UserHandler(db)
server := httptest.NewServer(handler)
defer server.Close()
// 3. Начинаем стрельбу: делаем запрос к серверу
resp, err := http.Get(server.URL + "/users/1")
assert.NoError(t, err)
// 4. Смотрим, выжил ли он
assert.Equal(t, http.StatusOK, resp.StatusCode)
// ... тут ещё можно тело ответа по косточкам разобрать
}
Чем это всё, блядь, характерно:
- Суть: Проверяем, как модули друг друга терпят в реальной жизни, а не в сказке с моками.
- Окружение: Требуется почти боевая обстановка — Docker-контейнеры с постгресами, Redis, файловые системы. Без этого нихуя.
- Скорость: Медленнее, чем юнит-тесты, просто пиздец как. Зато правдивее.
- Надёжность: Дают ощущение, что система не рассыпется в пыль при первом же реальном запросе. Хуй знает, может, и не рассыпется.