API-, интеграционное и E2E-тестирование
latest update of the page: 31-01-2023, 17:57 UTC
Определимся с предметом
Своими словами.
Тестирование API (API testing) = процесс тестирования приложения (сервиса) с целью проверки того, что реализация его внешних интерфейсов соответствует установленным требованиям. Чуть подробнее здесь.
Интеграционное тестирование (Integration testing) = проверка корректности взаимодействия чего-то с чем-то, в зависимости от контекста:
- либо проверка связи между модулями (компонентами) кода, а также взаимодействия с различными частями системы (операционной системой, оборудованием либо связи между различными системами)
- либо проверка интеграции между сервисами/системами. В настоящей "статье" мы будем говорить об этом.
Сквозное тестирование (End-To-End, E2E или Chain testing) = проверка некоей ценной для Клиента функциональности (feature) по всей "цепочке" её исполнения:
от инициирующих действий Клиента (либо клиентского приложения) в CLI / TUI / GUI / API / filesystem / DB -->
--> через взаимосвязанные системы/сервисы нашего Продукта -->
--> до предоставления Клиенту (его приложению) результата в обозначенном требованиями формате и месте.
Чуть подробнее здесь
Вступление
Изложенное ниже является очень сжатой компиляцией личного опыта, и не номинируется на истину в последней инстанции. То же касается приводимых определений.
Рассматривается тот участок процесса поставки, когда тестируемые системы/сервисы уже прошли своё "личное" функциональное тестирование, а теперь нам нужно убедиться, что они слаженно работают вместе как единый продукт.
Речь пойдёт о том как подступиться к интеграционному (системному) тестированию совокупности взаимодействующих систем/сервисов,
- которое предполагается автоматизировать
- при этом не используя заглушки (stubs) и моки (mocks), т.е. в максимально "живом и натуральном" окружении.
Какая интеграция вообще бывает?
Предположим, что мы знаем, что интеграция между приложениями в общем случае может происходить:
-
прямыми вызовами API "точка-точка" по шаблону request-reply (запрос-ответ) или one-way (отправка в одну сторону).
Обычно реализуется посредством REST API или RPC-взаимодействия.
-
обменом через слой среднего уровня, например через системы управления очередями (message brokers) типа RabbitMQ и Apache Kafka
или при посредстве КСШ (ESB) (которая, по-сути тоже является собой совокупность тех же message brokers)
-
обменом файлами, складываемыми/читаемыми в условленном "месте".
Таким местом может быть как некий общий локальный storage, так и удалённый, (от)куда файлы читаются/передаются по протколам FTP, SSH et cetera.
-
на уровне баз данных:
- одна общая БД для нескольких систем (привет монолитам и всяческому легаси)
- баз несколько, но связанных процессами ETL/ELT
Обследование
Обследуем сервисы/системы, составляющие наш условный Продукт, ища и изучая следующие информационные артефакты (список избыточный):
- Сценарии использования (use cases) и БТ (бизнес-требования) по ним
- Архитектура (общая, компонентная, интеграционная)
- Диаграммы последовательности (sequence diagram) интеграционных взаимодействий
- СТ (системные требования) к API, описание/контракты API
- Объектная модель (object model)
- Ролевая модель (role model)
- Диаграмма развёртывания (DD, deployment diagram), руководства/инструкции по установке и администрированию
Изучение их позволит обрести
понимание по каждому сервису/системе:
- список ВОПРОСОВ к команде сервиса/системы
- для чего вообще нужен, какие его самые важные фичи
- входящие интеграционные потоки
- исходящие интеграционные потоки
- как производит аутентификацию запросов
- как происходит авторизация
- какие протоколы где использует (требуются ли сертификаты и ключи)
- какими сущностями оперирует
- какие действия в GUI и/или запросы к API инициируют исходящие запросы в другие сервисы/системы
- для каких ролей эти действия должны быть доступны
- при каких способах развёртывания и каких именно настройках интеграция будет идти тем или иным образом
Это понимание И полученные ответы на ваши уточняющие вопросы должны позволить приступить к
разработке тестовых сценариев:
- определить необходимые предусловия (какая учётная запись с какими правами нужна для каких действий, экземпляры каких сущностей должны быть созданы в этой и смежных системах, какая д.б. конфигурация у сервиса/системы)
- составлять корректные шаги
- приоритизировать сценарии по уровню критичности проверяемой функциональности
Абстрактный пример обследуемой архитектуры
Предположим, мы имеем некий Продукт, состоящий из Системы А, Системы Б, Системы В. Продукт предоставляет Клиенту некое публичное API, в которое клиентское приложение постоянно пишет некие данные. Продукт также предоставляет Клиенту web-UI. Основным юзкейсом нашего Продукта является приём данных от Клиента, обработка их каким-то образом и предоставление в некотором человекочитаемом виде в web-UI. Также наш Продукт для каких-то внутренних потребностей собирает какие-то данные со своих Систем.
Для упрощения опустим интеграцию с системами аутентификации и авторизации.
скачать схему в формате diagrams.net (бывший draw.io)
В этом случае с точки зрения API / integration / E2E тестирования нас будут интересовать следующие элементы архитектуры:
- API 4 шт.
- Message broker 1 шт.
- Интеграционные потоки 4 шт.
Какие же тестовые сценарии?
Интеграционные тестовые сценарии можно поделить, например, на следующие группы (по возрастанию сложности):
-
Auth.
Тестовые сценарии на проверку возможности аутентификации и/или авторизации запросов к API. mTLS, basic-auth, JWT,... вот это вот всё. Можно совмещать с базовыми проверками ролевой модели, если это возможно сделать запросами к (web-UI) API.
-
API.
- В этой группе проверяем такие методы API, которые НЕ инициируют подзапросов в другие Системы, в противном случае это уже будут integration-тесты.
- Тесты, имеющие целью проверки того, что на запросы к методам API, составленные на основе требований и/или контракта этого API, приходит ответ, соответствующим требованиям/контракту.
-
Тесты, имеющие целью проверки того, что обращения к API позволяют успешно производить CRUD операции наl сущностями, которыми оперирует система-владелец API.
Успешность создания/изменения/удаления сущностей можно проверять как и цепочкой обращений к методам API (при наличии соответствующих), так и запросами к БД, если есть такая возможность.
-
Integration.
Тесты корректности интеграции двух систем. "Дёргаем" (по API / web-UI) первую систему, проверяем, что она корректно "пообщалась" с другой системой.
Порой, такой тест м.б. частным случаем E2E, если в реализации фичи (бизнес-процессе) задействовано всего 2 системы.
-
E2E.
Проверка такого бизнес-процесса (фичи, если угодно) ИТ-Продукта, в процессе выполнения которой задействовано 3 и более системы: система, в которой было совершено инициирующее воздействие (обращение к API, манипуляция в UI), "промежуточные" системы, система, в которой "даются" даные для итогового результата.
Рекомендуется соотношение одна фича = один E2E-тест (базовый положительный случай), потому что E2E — самые долгие и дорогие по автоматизации и поддержке тесты.
Какие же тесты по группам будут для нашего примера
API
скачать схему в формате diagrams.net (бывший draw.io)
Integration
скачать схему в формате diagrams.net (бывший draw.io)
E2E
скачать схему в формате diagrams.net (бывший draw.io)
Для ускорения E2E, или если вам кажется, что пункты 3 и 4 дублируют интеграционные тесты, то эти шаги в кейсе можно опустить, но тогда поиск неизбежных ошибок усложнится, потому что не будет сразу очевидно на каком участке затык. Так что здесь надо взвешивать что вам в вашем конкретном случае важнее.