API-, интеграционное и E2E-тестирование
latest update of the page: 30-08-2023, 17:33 UTC
Определимся с предметом
Своими словами:
Тестирование API (API testing) = процесс тестирования приложения (сервиса) с целью проверки того, что реализация его внешних интерфейсов соответствует установленным требованиям.
Сиречь, "щупаем" сами интерфейсы согласно имеющимся их описаниям, как будто мы некая внешняя система. Чуть подробнее здесь.
Интеграционное тестирование (Integration testing) = проверка корректности взаимодействия чего-то с чем-то, в зависимости от контекста:
- проверка взаимодействия модулей (компонентов) кода в рамках одного приложения
- проверка взаимодействия приложения с ОС (операционной системой) или оборудованием
- проверка интеграции между сервисами/системами. В настоящей "статье" мы будем говорить об этом.
Сиречь, "дёргаем"/наблюдаем нечто-1, инициирующее вызовы к нечто-2, проверяем, что взаимодействие происходит согласно имеющимся интеграционным описаниям обоих нечт: одно корректно "спрашивает", другое корректно "отвечает", и наборот, если взаимодействие двустороннее.
Сквозное тестирование (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 дублируют интеграционные тесты, то эти шаги в кейсе можно опустить, но тогда поиск неизбежных ошибок усложнится, потому что не будет сразу очевидно на каком участке затык. Так что здесь надо взвешивать что вам в вашем конкретном случае важнее.