Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Интеграционные тесты
Интеграционные тесты (Integration Tests) — это автоматические тесты, которые проверяют взаимодействие нескольких компонентов системы между собой, в отличие от unit-тестов, проверяющих отдельные функции в изоляции.
Различие с unit-тестами
# Unit-тест: тестирует одну функцию в изоляции
def test_calculate_discount():
discount = apply_discount(100, 0.1)
assert discount == 90 # Мокируем БД, не трогаем её
# Интеграционный тест: проверяет работу функции с реальной БД
def test_apply_discount_with_database():
user = create_user_in_db(name="Alice")
apply_discount(user.id, 0.1)
updated_user = get_user_from_db(user.id)
assert updated_user.balance == 90 # Реальная БД
Уровни тестирования (Test Pyramid)
E2E Tests (UI tests)
/ ^
/ \ Интеграционные тесты (10-20%)
/___________\
Unit Tests (70-80%) - фундамент
Элемент Скорость Надёжность Стоимость
Примеры интеграционных тестов
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Создаём БД для тестов
TESTING_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(TESTING_DATABASE_URL)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Интеграционный тест: API + БД
@pytest.fixture
def test_client():
Base.metadata.create_all(bind=engine)
with TestClient(app) as client:
yield client
Base.metadata.drop_all(bind=engine)
def test_create_user_and_retrieve(test_client):
# 1. Создаём пользователя через API
response = test_client.post("/users", json={"name": "Alice", "email": "alice@example.com"})
assert response.status_code == 201
user_id = response.json()["id"]
# 2. Получаем пользователя через API
response = test_client.get(f"/users/{user_id}")
assert response.status_code == 200
assert response.json()["name"] == "Alice"
# 3. Проверяем в БД напрямую
user = TestingSessionLocal().query(User).filter(User.id == user_id).first()
assert user.email == "alice@example.com"
Интеграционный тест с внешним API (с VCR)
import pytest
import vcr
import requests
# VCR записывает реальные HTTP-запросы в кассету
@pytest.mark.vcr
def test_payment_api_integration():
with vcr.VCR(cassette_library_dir="cassettes").use_cassette(payment_api.yaml):
response = requests.post(
"https://api.payment-provider.com/charge",
json={"amount": 100, "currency": "USD"}
)
assert response.status_code == 200
assert response.json()["status"] == "success"
Характеристики интеграционных тестов
| Характеристика | Unit-тест | Интеграционный | E2E |
|---|---|---|---|
| Скорость | Очень быстро | Медленнее | Медленно |
| Компоненты | Одна | Несколько | Вся система |
| Реальность | Мокирована | Частично реальна | Полностью реальна |
| Цель | Логика функции | Взаимодействие модулей | Пользовательский сценарий |
| Хрупкость | Стабильны | Средние | Хрупкие |
Лучшие практики
# ✅ Хорошо: чистая БД до каждого теста
@pytest.fixture(autouse=True)
def cleanup_db():
Base.metadata.create_all(bind=test_engine)
yield
Base.metadata.drop_all(bind=test_engine)
# ✅ Используй фикстуры для переиспользуемых ресурсов
@pytest.fixture
def authenticated_client():
client = TestClient(app)
client.headers["Authorization"] = "Bearer test_token"
return client
# ❌ Плохо: глобальное состояние, тесты зависят друг от друга
db = None # Глобальная переменная
user_id = None # Результат предыдущего теста
Вывод
Интеграционные тесты важны для проверки реального взаимодействия компонентов. Они медленнее unit-тестов, но ловят проблемы, которые юнит-тесты не видят (проблемы с БД, внешними API, конфигурацией). Идеальная пирамида: 70% unit-тестов, 20% интеграционных, 10% E2E.