Проверка взаимодействия компонентов
Проверка в БД — SQL для тестировщика, Основы БД, транзакции, PostgreSQL. Карта — о разделе.
Практикум №2. После первого юнит-теста проверяем связку компонентов — API + база, два сервиса, клиент и сервер. Unit ловит ошибки в функции; integration — "модули не понимают друг друга".
Play ITЗагрузка интерактивного демо…
Проверка взаимодействия компонентов
Интеграционное тестирование — проверка, что части системы вместе работают корректно — API пишет в БД, сервис A вызывает сервис B, очередь доставляет сообщение.
Данный этап разработки позволяет убедиться, что компоненты системы обмениваются данными согласно заранее определенным контрактам и ведут себя предсказуемо при совместной работе. Тестирование на этом уровне фокусируется не на внутренней логике отдельных частей, а на потоках данных и интерфейсах связи между ними.
Процесс проверки взаимодействия требует создания изолированной среды, которая имитирует реальные условия эксплуатации. В такой среде разработчики могут безопасно запускать сценарии, которые включают взаимодействие базы данных, серверного приложения и клиентских запросов. Отсутствие изоляции может привести к загрязнению тестовых данных реальными показателями или конфликтам с другими запущенными процессами.
Практический пример данной статьи демонстрирует полный цикл создания минимально жизнеспособного сервиса. Мы создадим структуру проекта, настроим базу данных для хранения информации, реализуем логику сохранения и извлечения записей, развернем веб-сервис и выполним проверку его работы через инструмент Postman. Этот подход позволяет увидеть, как данные перемещаются от клиента к серверу, сохраняются в хранилище и возвращаются обратно пользователю.
Создание тестовой базы данных
Первым шагом в построении системы является подготовка хранилища данных. База данных служит местом постоянного хранения информации, которую приложение использует для своей работы. Для практических целей мы выберем реляционную модель данных, так как она обеспечивает строгую целостность и простоту структуры для учебных примеров.
Выбор СУБД зависит от предпочтений команды и требований проекта. В данном случае мы используем PostgreSQL, так как это популярная открытая система с мощным функционалом и широкой поддержкой в экосистеме разработки. Установка PostgreSQL возможна на локальную машину разработчика или в контейнер Docker. Использование Docker позволяет создать чистое окружение, которое можно быстро удалить и восстановить без влияния на основную систему.
Создание схемы базы данных включает определение таблиц, полей и связей между ними. Таблица пользователей будет содержать уникальные идентификаторы, имена, электронные адреса и метки времени создания записи. Каждый элемент таблицы имеет определенный тип данных, который гарантирует корректность введенной информации. Например, поле идентификатора должно иметь тип целого числа с автоинкрементом, чтобы каждое новое сообщение получало уникальный номер.
Структура таблицы формируется с помощью языка SQL. Команда CREATE TABLE определяет имя таблицы и список колонок с их атрибутами. Ограничение PRIMARY KEY указывает на то, что значение в этой колонке должно быть уникальным для каждой строки. Ограничение NOT NULL запрещает сохранение пустых значений в определенных полях. Это обеспечивает качество данных на этапе их ввода.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
После выполнения скрипта создания таблицы необходимо убедиться в её работоспособности. Подключение к базе данных осуществляется через клиентское приложение или командную строку. Запрос SELECT позволяет проверить наличие таблицы и посмотреть текущее содержимое. Если таблица пуста, это означает, что структура создана успешно, но данные еще не добавлены.
Важным аспектом настройки является управление доступом. Разработчик должен создать пользователя с правами на чтение и запись только в рамках тестовой базы данных. Это предотвращает случайное удаление или изменение системных таблиц. Пароль пользователя должен храниться в защищенном месте и передаваться в конфигурационные файлы приложения через переменные окружения.
Тестовая база данных также должна поддерживать возможность очистки состояния между запусками тестов. Команда TRUNCATE TABLE удаляет все строки из таблицы, оставляя структуру нетронутой. Это позволяет начинать каждый новый тест с чистого листа и исключает влияние предыдущих запусков на результаты последующих проверок.
Разработка программы для работы с данными
На следующем этапе создается программный код, который реализует бизнес-логику взаимодействия с базой данных. Программа должна уметь сохранять новые записи, читать существующие данные и сравнивать поля для проверки их соответствия. Мы используем язык Python благодаря его простому синтаксису и наличию мощных библиотек для работы с базами данных.
Библиотека psycopg2 предоставляет драйвер для подключения к PostgreSQL из кода Python. Она позволяет выполнять SQL-запросы, управлять транзакциями и обрабатывать полученные результаты. Приложение создает соединение с базой данных, используя параметры подключения, указанные в конфигурации. Эти параметры включают адрес сервера, порт, имя базы данных, пользователя и пароль.
Функция сохранения записи принимает объект с данными пользователя и формирует команду INSERT. Эта команда передает значения имен, электронных адресов и других полей в соответствующие столбцы таблицы. После выполнения запроса система автоматически генерирует уникальный идентификатор для новой строки. Функция возвращает этот идентификатор, чтобы программа могла ссылаться на созданную запись в дальнейшем.
Чтение данных реализуется через команду SELECT. Программа запрашивает информацию по уникальному идентификатору или по другим критериям поиска. Результат запроса возвращается в виде коллекции объектов, где каждый объект соответствует одной строке из таблицы. Код преобразует сырые данные из базы в удобные для использования структуры внутри приложения.
Сравнение полей выполняется путем сопоставления ожидаемых значений с фактическими данными, полученными из базы. Если значения совпадают, функция возвращает сигнал об успехе. При обнаружении расхождений система фиксирует ошибку и описывает различия. Это позволяет выявить проблемы с логикой сохранения, ошибки форматирования данных или сбои в передаче информации.
Код ITЗагрузка примера кода…
Обработка ошибок является критически важной частью программы. События, такие как потеря соединения с базой данных, нарушение уникальности email или отсутствие записи по указанному ID, должны быть перехвачены и обработаны корректно. Программа не должна завершаться аварийно, а должна возвращать понятное сообщение об ошибке, которое поможет разработчику найти причину сбоя.
Транзакционная целостность обеспечивается использованием блоков try-except-finally. Если какая-либо операция внутри блока вызывает исключение, изменения откатываются, и база данных остается в исходном состоянии. Это гарантирует, что частичные операции не приведут к порче данных.
Модульность кода позволяет легко расширять функциональность. Добавление новых методов для обновления или удаления записей происходит по тому же принципу. Каждая функция отвечает за одну конкретную задачу, что упрощает тестирование и поддержку кода.
Реализация веб-сервиса и настройка API
Веб-сервис выступает посредником между клиентом и базой данных. Он принимает HTTP-запросы, выполняет необходимую логику обработки и возвращает ответы в формате JSON. Для реализации этого компонента мы используем фреймворк FastAPI, который обеспечивает высокую скорость работы и автоматическую генерацию документации.
FastAPI позволяет определять маршруты с использованием декораторов. Маршрут GET отвечает за получение данных, а маршрут POST — за создание новых записей. Каждый маршрут связан с функцией, которая содержит код обработки запроса. Фреймворк автоматически разбирает входящие данные, проверяет их типы и передает в функцию.
При получении запроса POST на создание пользователя, сервис извлекает тело запроса, валидирует данные и вызывает функцию сохранения из нашей программы. Если операция успешна, сервис возвращает статус 201 Created вместе с идентификатором созданной записи. Если возникает ошибка валидации или базы данных, возвращается статус 400 Bad Request с описанием проблемы.
Маршрут GET принимает идентификатор пользователя в качестве параметра пути. Сервис обращается к функции чтения, получает данные из базы и возвращает их в ответе со статусом 200 OK. Если запись не найдена, возвращается статус 404 Not Found. Это стандартное поведение RESTful-архитектуры, которое понятно всем разработчикам.
Конфигурация приложения включает подключение к базе данных и регистрацию зависимостей. Движок FastAPI автоматически создает интерактивную документацию Swagger UI по адресу /docs. Эта страница показывает все доступные методы, форматы входных данных и примеры ответов, что упрощает работу с сервисом.
Код ITЗагрузка примера кода…
Сервис должен быть запущен в отдельном процессе. Это позволяет ему работать независимо от базы данных и других компонентов. Логи запуска и остановки записываются в файл, что помогает отслеживать состояние системы в реальном времени.
Важно настроить CORS (Cross-Origin Resource Sharing), если клиентское приложение находится на другом домене. Настройка позволяет браузеру разрешать отправку запросов к вашему сервису извне. Без этого пользователь столкнется с ошибками безопасности при попытке взаимодействия.
Тестирование через Postman
Postman является одним из самых популярных инструментов для ручного тестирования API. Он позволяет отправлять запросы различных типов, просматривать ответы и анализировать их содержимое. Интерфейс Postman интуитивно понятен и поддерживает создание коллекций запросов для удобства повторного использования.
Для начала работы необходимо создать новую коллекцию и добавить в неё два запроса: один для метода POST и другой для метода GET. URL каждого запроса указывает на адрес вашего локального сервиса, например, http://localhost:8000/users/. Метод POST используется для отправки тела запроса с данными нового пользователя. Метод GET требует указания идентификатора пользователя в конце URL.
При создании запроса POST следует перейти во вкладку Body и выбрать формат JSON. В поле ввода нужно написать данные в формате ключ-значение. Пример запроса выглядит следующим образом:
{
"name": "Алексей Иванов",
"email": "alexey@example.com"
}
После нажатия кнопки Send Postman отправляет запрос на сервер и отображает ответ. В верхней части окна отображается статус-код ответа, например, 201. В теле ответа содержится информация о созданной записи, включая сгенерированный идентификатор.
Запрос GET выполняется путем указания полного URL с идентификатором, полученным из предыдущего шага. Например, http://localhost:8000/users/1. Отправка запроса возвращает объект пользователя с теми же данными, которые были переданы при создании. Статус-код в этом случае составляет 200.
Postman позволяет сохранять историю запросов и копировать их в другие инструменты. Также доступна функция просмотра заголовков ответа, которые содержат информацию о формате контента и времени обработки. Анализ этих данных помогает понять, как сервер реагирует на разные типы запросов.
Анализ ответов и кодов состояния
Коды состояния HTTP являются основным языком общения между клиентом и сервером. Они сообщают о результате выполнения запроса без необходимости чтения тела ответа. Понимание этих кодов необходимо для правильной интерпретации результатов тестирования.
Статус 200 OK означает, что запрос выполнен успешно, и сервер вернул запрошенные данные. Статус 201 Created подтверждает, что ресурс был создан и теперь доступен по указанному адресу. Эти коды указывают на положительный результат теста.
Статус 400 Bad Request сигнализирует о том, что клиент отправил некорректные данные. Это может произойти при отсутствии обязательных полей или несоответствии формата. Статус 404 Not Found говорит о том, что запрашиваемый ресурс не существует. Статус 500 Internal Server Error указывает на внутреннюю ошибку сервера, которая требует внимания разработчиков.
При анализе ответа важно обратить внимание на заголовки. Заголовок Content-Type должен указывать на формат данных, обычно application/json. Время ответа показывает производительность системы. Если время превышает нормативные значения, это может свидетельствовать о проблемах с базой данных или перегрузке сервера.
Тело ответа должно точно соответствовать ожидаемой структуре. Поля name и email должны содержать те же значения, что и в запросе. Идентификатор должен быть числом и увеличиваться с каждым новым созданием записи. Любые отклонения от этого шаблона требуют расследования.
Анализ ошибок и обработка исключений
Ошибки в интеграционном взаимодействии могут возникать на разных уровнях. Самая частая проблема — это нарушение целостности данных, например, попытка сохранить пользователя с уже существующим email. Сервер должен вернуть ошибку 409 Conflict, чтобы сообщить клиенту о дублировании.
Если база данных недоступна, сервис должен обработать это исключение и вернуть статус 503 Service Unavailable. Клиентская часть может использовать эту информацию для повторной попытки запроса через несколько секунд. Аварийное завершение работы приложения недопустимо, так как оно нарушает доступность сервиса.
Логирование ошибок играет ключевую роль в диагностике проблем. Сервис должен записывать детали сбоев в файл, включая стек вызовов и контекст запроса. Это позволяет разработчикам быстро находить корневую причину проблемы даже в сложных распределенных системах.
Тестирование граничных условий помогает выявить скрытые уязвимости. Например, передача слишком длинного имени или специально сформированного email может вызвать сбои в работе программы. Правильная валидация входных данных предотвращает такие ситуации.
Обработка ошибок должна быть последовательной и предсказуемой. Все исключения должны переводиться в понятные сообщения для пользователя. Технические детали должны скрываться от конечного потребителя, но оставаться доступными для администраторов системы.
Минимальный интеграционный тест в коде
Проверка через Postman полезна для первичной диагностики. Для регулярного прогона в CI лучше добавить автотест, который поднимает API и отправляет реальные HTTP-запросы.
Пример идеи на pytest + requests:
Код ITЗагрузка примера кода…
Этот формат даёт стабильную регрессию по критичному пользовательскому потоку "создать и прочитать запись".
Что обязательно проверить кроме "200/201"
Сильный интеграционный сценарий включает позитивные и негативные ветки:
- дубликат
emailвозвращает ожидаемый код (обычно409); - чтение несуществующего
idвозвращает404; - невалидный JSON или пустые поля возвращают
400/422; - сервис держит разумное время ответа при серии запросов;
- лог ошибки содержит контекст для диагностики (trace id, id запроса, endpoint).
Такой набор быстро показывает качество контракта между клиентом, API и БД.
Практика для командной работы
Чтобы тесты взаимодействия приносили пользу на проекте, договоритесь о трёх вещах:
- Контракт API: схема запроса/ответа и коды ошибок фиксируются в OpenAPI.
- Тестовые данные: каждый прогон стартует с предсказуемого состояния БД.
- Владение тестами: кто чинит падающий интеграционный тест и в какой SLA.
Связанные материалы: API-тестирование, интеграционный уровень, жизненный цикл тестирования, основы интеграционного взаимодействия.
Инцидентный кейс — ошибка на стыке сервисов
После релиза заказ создаётся, но письмо-подтверждение не уходит. Unit-тесты зелёные, проблема живёт в интеграции.
Рабочий разбор:
- проверяют корреляционный id запроса в API, очереди и сервисе уведомлений;
- сверяют контракт сообщения — поля, обязательные значения, версию схемы;
- запускают интеграционный ретест на проблемном сценарии;
- добавляют автотест на этот стык в регулярный regression-набор.
Так команда превращает единичный инцидент в постоянную защиту от повторения.
Шаблон артефакта — integration checklist
Короткий чек-лист для релизной проверки интеграций:
Integration Checklist:
[ ] Контракты API обновлены (OpenAPI/schema)
[ ] Проверены коды ошибок 4xx/5xx
[ ] Проверен idempotency key для повторных запросов
[ ] Проверена корреляция trace id между сервисами
[ ] Подготовлены тестовые данные и очистка после прогона
[ ] Добавлен regression-тест на найденный дефект
Чек-лист удобно хранить рядом с тест-планом релиза.
Готовые поля для Jira и YouTrack
Issue Type: Bug
Summary: [INTEGRATION] Ошибка на стыке Service A -> Service B
Contract Version: vX.Y
Request/Response Sample: ...
Trace ID / Correlation ID: ...
Observed Status Code: ...
Expected Status Code: ...
Impact: сколько пользователей/операций затронуто
Retest Plan:
[ ] Confirmation
[ ] Target regression
[ ] Добавление интеграционного автотеста
Пример заполнения:
Issue Type: Bug
Summary: [INTEGRATION] Order -> Notification не отправляет email при статусе PAID
Contract Version: v3.4
Request/Response Sample: POST /events {"orderId": 5512, "status":"PAID"}
Trace ID / Correlation ID: a84e6d2f...
Observed Status Code: 202 от Order, затем 500 в Notification
Expected Status Code: 202 и успешная доставка email
Impact: 18% оплаченных заказов без письма-подтверждения
Retest Plan:
[x] Confirmation
[x] Target regression
[x] Добавление интеграционного автотеста
Навигация по разделу "Тестирование"
- Маршрут: О разделе · Резюме раздела · Карта уровней и практик (Unit / Integration / UI / E2E, TDD, BDD)
- Теория и процесс: Основы · Классификация · Жизненный цикл · Порядок этапов · Артефакты качества
- Уровни проверок: Unit · Integration · E2E, системное и UI · API · Тестовые дублёры · Покрытие кода · White-box · Мутационное тестирование
- Практика QA: Документация · Тест-дизайн · Ручное веб · SQL
- Автоматизация: Стратегия и пирамида · Каталог инструментов · Selenium · Playwright
- Практикум и углубление: Подготовка среды и создание первого теста · Проверка взаимодействия компонентов · Проверка пользовательского сценария · Проверка надежности под нагрузкой · Мобильное · Нагрузка · Безопасность · Самопроверка · Доп. материалы курса · Инструменты с низким кодом для тестирования · Тестирование нейроморфных систем