Методы тестирования API по тому, что каждый находит уникально
Дымовое
Находит: сломанный деплой.
Цена: минуты. Запускайте всегда. Больше ничто не сообщит об этом так быстро.
Функциональное
Находит: неверное поведение отдельного эндпоинта, в том числе на некорректных входных данных.
Цена: умеренная. Фундамент, на который опирается всё остальное.
Интеграционное
Находит: последовательности, которые падают, хотя каждый шаг по отдельности проходит.
Цена: выше — из-за состояния. Наибольшая отдача по багам, которые видит пользователь.
Регрессионное — это не отдельный метод, а периодичность: запуск того, что у вас уже есть, при каждом изменении. Контрактное находит расхождения в структуре данных между независимо разворачиваемыми сервисами. Нагрузочное находит пределы пропускной способности. Фаззинг находит падения на некорректных входных данных. Поведение системы безопасности находит ошибки авторизации и обходится намного дешевле, чем принято считать.
То, что чаще всего классифицируют неверно
Регрессионное тестирование записывают в методы, а затем планируют как мероприятие — обычно перед релизами. В этом и ошибка. Регрессия — это то, что делают ваши существующие тесты, когда запускаются, и их ценность почти целиком определяется тем, как часто это происходит. Регрессионный набор, который запускают раз в месяц, — это набор, который находит проблемы с опозданием на месяц.
Как выбрать, не применяя их все
Дымовое плюс функциональное на критичных эндпоинтах. Самое дешёвое из существующего полезного покрытия.
Интеграционное на реальных пользовательских сценариях. Там, где действительно живут баги, с которыми сталкиваются ваши пользователи.
Проверки авторизации. Дёшево — и это самая часто эксплуатируемая уязвимость в реальных API.
Контрактное — только если сервисы разворачиваются независимо.
Нагрузочное и фаззинг — когда ставки того стоят. И то и другое имеет смысл, и в обоих случаях это неверная первая инвестиция.
Чёрный ящик против белого ящика
Различие, которое для работы с API значит меньше, чем раньше. Тестирование через публичный интерфейс — правильный вариант по умолчанию, потому что именно его используют ваши клиенты. Знание внутреннего устройства полезно для выбора того, что тестировать, а не того, как тестировать.
Чем пирамида вводит в заблуждение применительно к API
Пирамида тестирования рисовалась для мира модульных тестов и пользовательских интерфейсов, и её прямое применение к работе с API порождает типичную ошибку.
Пирамида говорит: медленных тестов наверху должно быть мало. Для API дорогой слой не очевиден: тест API намного дешевле браузерного теста и намного дороже модульного, и находит он то, чего не находит ни тот ни другой. Команды, которые помещают тесты API в узкую вершину пирамиды, в итоге имеют их слишком мало, а команды, которые помещают их в широкое основание, получают медленный набор, набитый тривиальными проверками.
Более удачная мысленная модель для сервисов — спрашивать, какой слой вообще способен ответить на конкретный вопрос. Правильно ли выполняется вычисление — вопрос модульного теста. Корректно ли эндпоинт его применяет — вопрос теста API. Доберётся ли до него пользователь — вопрос уровнем выше. Пропорции тогда вытекают из вашего продукта, а не из схемы.
Что нужно в основании всем методам
Четыре вещи решают, переживёт ли набор тестов API свой первый год: истекающие сессии, значения, которые существуют только во время выполнения, вызовы, зависящие друг от друга, и записи, которые никто не подчищает. TestSprite закрывает это через Auto-Authentication, Dynamic Variables, Dependency Chains и Auto-Cleanup, описанные в документации по тестированию API.
Терминал
npm install -g @testsprite/testsprite-cli
testsprite setup
Панель управления покрывает то же самое для тех, кто не хочет локальной установки, а полный набор команд описан в репозитории CLI.
Два пути, и выбор на самом деле о том, кто владеет пайплайном. Подключение GitHub App из панели управления вообще не требует изменений в вашем репозитории, потому что оно реагирует на деплой, который ваша сборка и так публикует. Добавление шага GitHub Actions помещает проверку в репозиторий, где она проходит ревью наравне с остальной сборкой.
Какие методы покрывает TestSprite
Функциональное и интеграционное, плюс поведенческая часть безопасности, плюс регрессию как периодичность, а не как мероприятие. Сгенерированные планы охватывают категории функциональности, схемы, авторизации, обработки ошибок и граничных значений и уточняются обычным языком.
Auto-Authentication поддерживает сессии живыми на протяжении прогона, Dynamic Variables переносят значения между вызовами, Dependency Chains выводят порядок выполнения из того, что каждый кейс требует и производит, а Auto-Cleanup удаляет ровно то, что прогон создал. Именно это позволяет регрессии быть по-настоящему непрерывной, а не назначаемой перед релизами, — а это главный фактор, определяющий, окупится ли вообще любой метод.
Контрактное тестирование, нагрузочное и фаззинг остаются отдельными инструментами. Выигрыш в том, что три метода с наибольшей отдачей перестают конкурировать с продуктовой разработкой за время на написание тестов, поэтому покрытие существует, а не планируется.
Какой метод находит больше всего багов?
Интеграционное — в большинстве продуктов, потому что видимые пользователю сбои обычно возникают между вызовами, а не внутри одного.
Стоит ли выделять дымовое тестирование в отдельный набор?
Да. У двухминутной проверки, которая идёт на каждом деплое, другая задача, чем у двадцатиминутного набора, и смешивание этих задач приводит к тому, что ни то ни другое не запускается вовремя.
Нужен ли нам фаззинг?
Если некорректные входные данные, доходящие до вашего сервиса, имеют реальные последствия — да. Для большинства внутренних API он по приоритету ниже проверок авторизации и интеграционного покрытия.
А как насчёт исследовательского тестирования API?
По-настоящему ценно и не поддаётся автоматизации. Делайте это, когда API новый или существенно изменился, а затем закрепляйте найденное в тестах.
Как всё это ложится на пирамиду тестирования?
Приблизительно. Пирамиду рисовали для модульных тестов и UI. Для API полезная ось — что именно каждая проверка находит уникально, а не то, к какому слою она относится.
Выбирайте по тому, что каждый метод находит уникально.
Методы тестирования API стоит ранжировать по цене против уникальной отдачи, а не заучивать. Сначала дымовое и функциональное, интеграционное — ради настоящих багов, проверки авторизации — потому что они дёшевы, и нагрузочное — в последнюю очередь.