Четыре уровня функционального тестирования API

1. Статус

  • Вернулся ли 200.

  • Ловит недоступность сервиса. Спокойно проходит на пустом результате там, где должна быть запись.

2. Структура

  • Есть ли ожидаемые поля и того ли они типа.

  • Ловит расхождения схемы. Ничего не говорит о том, верны ли значения.

3. Значение

  • Действительно ли итог равен сумме, тот ли это статус, который должно давать данное действие.

  • Здесь начинают ловиться настоящие дефекты.

Четвёртый уровень — связи: после создания заказа виден ли он при запросе клиента. Самые интересные баги живут между двумя вызовами, а не внутри одного, и четвёртый уровень — единственный, который туда смотрит.

Почему наборы тестов останавливаются на втором уровне

Потому что третий и четвёртый уровни требуют знания того, что значит «правильно», а значит, кто-то должен это решить. Статус и структуру можно механически вывести из спецификации. Значения и связи требуют суждения о продукте.

Это действительно сложнее — и в этом вся ценность. Набор тестов, который не выражает ни одного правила продукта, всего лишь изощрённо проверяет, что сервис доступен.

Негативный сценарий, который пропускают

Для каждого эндпоинта спросите, что должно быть отклонено, и проверьте, что это так. Значения вне допустимого диапазона, отсутствующие обязательные поля, идентификатор, принадлежащий кому-то другому. Сервисы, возвращающие 200 с объектом ошибки в теле, встречаются достаточно часто, и набор тестов, не знающий об этом паттерне, будет вечно показывать зелёный.

Что нужно набору тестов под капотом

Переживёт ли набор тестов API свой первый год, решают четыре вещи: истекающие сессии, значения, существующие только во время выполнения, вызовы, зависящие друг от друга, и записи, которые никто не убирает. В TestSprite за это отвечают Auto-Authentication, Dynamic Variables, Dependency Chains и Auto-Cleanup, описанные в документации по тестированию API.

Именно это позволяет тратить внимание на третий и четвёртый уровни, а не на инфраструктуру.

Как вывести покрытие за пределы поверхностных проверок

Сгенерированные планы строятся на основе спецификации или прохода обнаружения API и включают категории функциональных проверок, схемы, авторизации, обработки ошибок и граничных значений, так что негативные сценарии есть по умолчанию, а не зависят от того, вспомнит ли о них кто-то в конце спринта.

Терминал

npm install -g @testsprite/testsprite-cli
testsprite setup

То же самое доступно в панели TestSprite, если вы предпочитаете ничего не устанавливать локально. Остальные возможности CLI описаны в репозитории CLI.

Как выбрать эндпоинты для четвёртого уровня

Проверки связей самые ценные и самые дорогие, поэтому они нужны не везде. Рабочий фильтр — спросить, во что обойдётся неверный ответ.

Всё, что двигает деньги, меняет права доступа или ложится в основу чужого решения, получает четвёртый уровень. Заказ, который существует, но не привязан к клиенту; выдача прав, прошедшая только на одной стороне; отчёт, внутренне непротиворечивый, но расходящийся с исходными записями. Это те сбои, которые дорого обходятся и происходят тихо.

Эндпоинтам отчётности только на чтение, проверкам работоспособности и всему, чей вывод человек сразу видит глазами, это не нужно. Осознанный выбор здесь и держит набор тестов достаточно быстрым, чтобы его запускали.

Запускайте на каждое изменение

Два пути, и выбор по сути сводится к тому, кто владеет пайплайном. Подключение GitHub App из панели вообще не требует изменений в репозитории, потому что реагирует на деплой, который ваша сборка и так публикует. Добавление шага GitHub Actions помещает проверку в репозиторий, где её ревьюят так же, как остальную сборку.

Как TestSprite выводит вас за пределы второго уровня

Сгенерированные планы по умолчанию включают негативные сценарии — в категориях функциональных проверок, схемы, авторизации, обработки ошибок и граничных значений, — а именно на них у большинства написанных вручную наборов заканчиваются силы. Вы уточняете планы обычным языком, и через это уточнение в набор тестов попадает ваше знание продукта.

Уровни значений и связей — те, что заслуживают вашего внимания, и те, для которых нужен человек, знающий продукт. Auto-Authentication поддерживает сессии живыми на протяжении всего прогона, Dynamic Variables переносят значения между вызовами, Dependency Chains выводят порядок выполнения из того, что каждому кейсу нужно и что он производит, а Auto-Cleanup удаляет ровно то, что создал прогон, — так что ваше время уходит на то, что значит «правильно», а не на инфраструктуру.

В результате вы получаете набор тестов, который проверяет тела ответов и связи между вызовами и запускается на каждое изменение, а не зелёный пайплайн, доказывающий, что сервис доступен.

Бесполезна ли проверка статус-кода?

Нет, это просто нижняя планка. Оставьте её и добавьте хотя бы одну проверку уровня значений для каждого значимого эндпоинта.

Как решить, что значит «правильно»?

Спрашивайте, что обещает продукт, а не что делает код. Если для какого-то эндпоинта ответа ни у кого нет, сама эта неопределённость стоит того, чтобы её вынести на поверхность.

Нужны ли все четыре уровня каждому эндпоинту?

Нет. Приберегите третий и четвёртый уровни для эндпоинтов, где неверное значение имеет последствия. Эндпоинтам отчётности и проверкам работоспособности они не нужны.

А что насчёт сгенерированных проверок?

Они полезны для первого и второго уровней — те механические. Третий и четвёртый выигрывают от ревью, потому что именно там в набор входит знание продукта.

Сколько негативных сценариев на эндпоинт?

Один-два значимых лучше десяти, перебирающих все возможные некорректные входные данные. Выбирайте те отказы, которые вызвал бы настоящий клиент.

Коротко

Статус и структура — это нижняя планка, а не вся работа.

В функциональном тестировании API есть четыре уровня проверок, и большинство наборов останавливается на втором. Дефекты ловят проверки значений и связей, а негативный сценарий — как раз то, что пропускают.