Основы интеграционного тестирования
Интеграционные тесты проверяют, как несколько компонентов или систем работают вместе. В то время как Unit Tests тестируют отдельные модули изолированно, интеграционные тесты гарантируют, что модули, базы данных и внешние сервисы правильно взаимодействуют друг с другом.
Кратко
- Интеграционные тесты проверяют взаимодействие компонентов или систем.
- Они выявляют ошибки, которые не обнаруживают чистые Unit Tests.
- Стратегии: Big Bang, Top-Down, Bottom-Up и Sandwich.
- Testcontainers, локальные In-Memory базы данных и staging-окружения — распространённые инструменты.
Определение
Integration Test объединяет несколько компонентов для проверки их интерфейсов и совместного поведения. При этом используются реальные зависимости, такие как базы данных, Message Queues или API, либо они заменяются лёгкими тестовыми подделками. Интеграционные тесты медленнее и сложнее Unit Tests, но покрывают более реалистичные сценарии.
Стратегии интеграционного тестирования
Big Bang Integration
Все модули собираются и тестируются одновременно. Подход простой, но отладка затруднена, так как источники ошибок трудно локализировать.
Top-Down Integration
Тестирование начинается с верхнего уровня управления и движется вниз. Нижние модули, ещё не доступные, заменяются stubs.
Bottom-Up Integration
Тестирование начинается с самых нижних модулей и движется вверх. Драйверы заменяют ещё не интегрированные верхние модули.
Sandwich Integration
Комбинация Top-Down и Bottom-Up. Одновременное тестирование сверху и снизу даёт результаты быстрее.
Основные инструменты
- Testcontainers: Docker-контейнеры для баз данных, Message Brokers и кэшей в тестах.
- H2 / SQLite: Лёгкие In-Memory базы данных для быстрых тестов.
- REST Assured: Тестирование HTTP API в Java.
- Supertest: Тестирование HTTP API в Node.js.
- Spring Boot Test: Интеграционные тесты для Spring-приложений.
Практический пример: интеграция API с базой данных
import unittest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.main import app, get_db
from app.models import Base
SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.create_all(bind=engine)
def override_get_db():
db = TestingSessionLocal()
try:
yield db
finally:
db.close()
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
class TestItemApi(unittest.TestCase):
def test_create_item(self):
response = client.post("/items/", json={"name": "Tastatur", "price": 49.99})
self.assertEqual(response.status_code, 201)
self.assertEqual(response.json()["name"], "Tastatur")
def test_read_item(self):
client.post("/items/", json={"name": "Maus", "price": 19.99})
response = client.get("/items/1")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()["name"], "Maus")
if __name__ == '__main__':
unittest.main()
Преимущества и недостатки
Преимущества
- Более реалистичное выявление ошибок: ошибки интерфейсов, проблемы с форматом данных и ошибки зависимостей становятся видны.
- Покрытие реальных сценариев: проверяется интеграция с базами данных, API и системами обмена сообщениями.
- Уверенность в архитектуре: подтверждается правильное взаимодействие компонентов.
- Раннее выявление проблем: интеграционные проблемы обнаруживаются до production.
Недостатки
- Длительное время выполнения: интеграционные тесты медленнее Unit Tests.
- Больше затрат на поддержку: нужно управлять тестовыми данными, окружениями и состояниями.
- Сложность локализации ошибок: источники ошибок труднее изолировать, чем в Unit Tests.
- Нестабильные тесты: зависимость от времени выполнения или внешних сервисов может привести к неустойчивым результатам.
Ключевые моменты
- Различие между Unit Tests и интеграционными тестами.
- Четыре стратегии интеграционного тестирования.
- Преимущества и ограничения интеграционного тестирования.
- Важные инструменты для тестирования интеграции с базами данных и API.
- Управление тестовыми данными и зависимостями.
Типичные вопросы с кратким ответом
-
Что проверяет Integration Test? Взаимодействие нескольких компонентов или систем.
-
Назови две стратегии интеграционного тестирования. Big Bang, Top-Down, Bottom-Up или Sandwich.
-
Что такое stub? Упрощённый модуль-заменитель для ещё недоступного компонента.
-
Почему интеграционные тесты медленнее Unit Tests? Они используют реальные базы данных, сетевые соединения или внешние сервисы.
-
Какое преимущество интеграционных тестов перед Unit Tests? Они выявляют ошибки интерфейсов и проблемы во взаимодействии компонентов.
Продолжение обучения в курсе Software Testing
Следующий материал в курсе Software Testing посвящён E2E Tests Grundlagen — как тестируются полные пользовательские сценарии.
Основные источники
- https://martinfowler.com/bliki/IntegrationTest.html
- https://www.testcontainers.org
- https://en.wikipedia.org/wiki/Integration_testing



