Почему вообще заходит речь об 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 на его собственном уровне, а по-настоящему сквозные тесты пишите намеренно.