Почему вообще заходит речь об API-тестировании с Selenium
Причины три, и по-настоящему хороша только одна.
Набор тестов уже есть. В CI есть задача с Selenium, все умеют её запускать, и добавить туда проверки API — путь наименьшего сопротивления. Это понятно, но причина здесь организационная, а не техническая.
Сценарий затрагивает и то, и другое. Отправить форму, а затем убедиться, что созданная через API запись корректна. Вот это законный случай, и именно под него стоит проектировать.
Подготовка и очистка. Создание тестовых данных через API, потому что через интерфейс это медленно. Разумно, но это обвязка, а не тестирование.
Чего это стоит
| Медленная обратная связь | Запуск браузера съедает основное время проверки, которая могла бы быть одним запросом. Набор тестов, который идёт двадцать минут, запускают реже — и вот это настоящая потеря. |
| Непонятные причины падений | Когда падает комбинированный тест, приходится выяснять, что именно сломалось — интерфейс или API. Раздельные наборы дают этот ответ сразу. |
| Покрытие, которое диктует UI | В итоге вы покрываете те эндпоинты, которые интерфейс вызывает сам по себе, а это лишь часть всей поверхности. Коды ошибок и граничные параметры так и остаются непроверенными. |
Разделение, которое работает
Оставьте Selenium для того, на что может ответить только браузер: работает ли сценарий, который видит пользователь. API покрывайте на его собственном уровне, где проверка — это запрос, а не загрузка страницы. Обращайтесь к API из набора Selenium только для подготовки и очистки, где важна скорость и никаких проверок не выполняется.
Единственный по-настоящему сквозной случай — отправить форму и проверить, что сохранил бэкенд, — стоит писать намеренно, а не случайно. Таких тестов немного, и они окупаются.
С чем должен справляться отдельный слой API-тестов
Переживёт ли набор API-тестов свой первый год, решают четыре вещи, каким бы инструментом вы ни пользовались: истекающие сессии, значения, которые существуют только во время выполнения, вызовы, зависящие друг от друга, и записи, которые никто не убирает. В TestSprite это называется Auto-Authentication, Dynamic Variables, Dependency Chains и Auto-Cleanup, а документация по API-тестированию описывает механику.
Именно эти четыре вещи отличают набор тестов, который живёт долго, от того, который удаляют через два квартала, и решать их на уровне API намного проще, чем навешивать на браузерный набор.
Подготовка данных, сделанная правильно
Создание тестовых данных для браузерного теста через API — единственное место, где эти два уровня действительно сходятся, и делать это стоит намеренно, а не случайно.
Правило, которое удерживает всё в порядке: подготовительные вызовы никогда ничего не проверяют. Их задача — как можно быстрее привести систему в известное состояние, и если такой вызов не сработал, тест должен завершиться ошибкой, а не падением, потому что неудавшаяся подготовка данных — это проблема инфраструктуры, а не дефект продукта. Если смешивать одно с другим, получится набор, где половина красного — шум.
Второе правило: всё, что создала подготовка, удаляет очистка — по привязке к конкретному тесту, а не по совпадению имён. Браузерные наборы накапливают данные быстрее, чем кто-либо ожидает, и список, который каждую неделю открывается всё медленнее, — это обычно так и не написанная очистка.
Как запускать и то, и другое
Наборам не нужно знать друг о друге. Selenium запускается в вашей CI-задаче так же, как и сегодня, а покрытие API работает рядом.
Если пайплайн принадлежит другой команде, то GitHub App — путь наименьшего сопротивления: это вебхук, он ничего не меняет в вашем репозитории и срабатывает, когда ваша сборка сообщает, что новая версия развёрнута. Если же вы хотите, чтобы проверка была видна прямо в репозитории, это сделает шаг GitHub Actions . Смотрите репозиторий CLI.
Что TestSprite покрывает на уровне API
TestSprite берёт на себя отдельный слой API-тестов, так что вам не нужно навешивать его на браузерный набор. API Discovery перечисляет всё, что отдаёт запущенный сервис, plan generation предлагает тест-кейсы по категориям: функциональные проверки, схема, авторизация, обработка ошибок и граничные значения, — а вы уточняете их обычным языком.
Четыре проблемы состояния решены на стороне продукта, а не вашей инфраструктуры: Auto-Authentication поддерживает сессии живыми, Dynamic Variables переносят значения между вызовами, Dependency Chains выводят порядок выполнения, Auto-Cleanup удаляет то, что создал прогон. Именно из-за этого набор API-тестов тяжело поддерживать в рабочем состоянии, и на уровне API всё это решается гораздо проще, чем внутри браузерного раннера.
Ваш набор тестов на Selenium остаётся на месте и покрывает то, на что может ответить только браузер. Оба запускаются из одного пайплайна.
Может ли Selenium отправлять HTTP-запросы напрямую?
Через языковые привязки — да, ведь вы просто пишете код. Вопрос в другом: нужна ли здесь браузерная сессия вообще, и для чистой проверки API ответ обычно отрицательный.
Стоит ли мигрировать наш набор тестов на Selenium?
Не целиком. Набор тестов на Selenium, которому доверяют, — это актив. Добавьте покрытие API на его собственном уровне, вместо того чтобы что-то переносить.
Как тестировать сценарий, который затрагивает и то, и другое?
Пишите его одним тестом и намеренно, держите количество таких тестов небольшим и делайте проверки достаточно конкретными, чтобы падение сразу показывало, какая сторона сломалась.
Playwright для этого лучше?
У него есть полноценный API для запросов, поэтому механика приятнее. Архитектурный аргумент от этого не меняется: браузерные проверки и проверки API отвечают на разные вопросы, и их лучше держать раздельно.
А как быть с аутентификацией на обоих уровнях?
Общим должен быть источник учётных данных, а не сессия. Каждый уровень должен получать собственную сессию, чтобы сбой в одном не перекидывался на другой.
Используйте браузер для браузерных вопросов.
API-тестирование с Selenium обычно сводится к координации двух видов проверок, а не к попытке заставить один инструмент делать и то, и другое. Оставьте Selenium для пользовательских сценариев, покрывайте API на его собственном уровне, а по-настоящему сквозные тесты пишите намеренно.