← Назад к вопросам

Что такое интеграционные тесты?

1.3 Junior🔥 251 комментариев
#Тестирование

Комментарии (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.