Ответ
Модульное (Unit) тестирование проверяет изолированно минимальную единицу кода (функцию, метод, класс). Интеграционное тестирование проверяет взаимодействие и совместную работу нескольких модулей или систем.
Ключевые различия:
| Критерий | Модульное тестирование | Интеграционное тестирование |
|---|---|---|
| Объект | Один класс или функция. | Группа классов, модулей, внешние системы (БД, API). |
| Изоляция | Полная. Зависимости заменяются тестовыми двойниками (Mock, Stub). | Минимальная. Используются реальные или приближённые к реальным зависимости. |
| Скорость | Очень быстрое (миллисекунды). | Медленное (секунды, минуты). |
| Цель | Проверить корректность логики единицы кода. | Проверить корректность взаимодействия и поток данных между компонентами. |
| Частота запуска | При каждом коммите (CI). | Реже (ночью, перед релизом). |
Пример модульного теста (с Mock):
# Тестируем сервис, изолировав его от реальной базы данных
from unittest.mock import Mock
def test_user_service_get_user():
# 1. Создаём мок репозитория
mock_repo = Mock()
mock_repo.find_by_id.return_value = User(id=1, name="Alice")
# 2. Внедряем мок в тестируемый сервис
service = UserService(mock_repo)
# 3. Вызываем метод и проверяем логику
result = service.get_user_profile(1)
# 4. Проверяем, что сервис корректно обработал данные от репозитория
assert result["name"] == "Alice"
# Проверяем взаимодействие: метод репозитория был вызван с правильным аргументом
mock_repo.find_by_id.assert_called_once_with(1)
Пример интеграционного теста:
# Тестируем взаимодействие сервиса с реальной (например, тестовой) БД
def test_user_creation_flow():
# 1. Поднимаем тестовую БД (Docker, in-memory)
db = start_test_database()
repo = UserRepository(db.connection)
service = UserService(repo)
# 2. Выполняем операцию, затрагивающую несколько слоёв
new_user = service.create_user("test@example.com", "password123")
# 3. Проверяем результат через прямое обращение к БД
user_from_db = repo.find_by_id(new_user.id)
# 4. Проверяем согласованность данных и состояние системы
assert user_from_db is not None
assert user_from_db.email == "test@example.com"
assert user_from_db.is_active is True # Проверка бизнес-логики, применённой при создании
Практическое правило: Пирамида тестов — много быстрых модульных тестов в основании, меньше интеграционных наверху.