Что на самом деле измеряет нагрузочное тестирование API

Пропускная способность: сколько запросов в секунду выдерживает сервис, прежде чем задержки начнут расти. Ответ получают, генерируя параллельный трафик и наблюдая за временем ответа и долей ошибок.

Корректность: содержит ли ответ то, что нужно. Ответ получают, проверяя тела ответов на соответствие ожиданиям.

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

Что функциональный набор тестов говорит о нагрузке, а что нет

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

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

Три вещи, которые стоит проверить, прежде чем вообще запускать нагрузочный тест

Работает ли это корректно при одном запросе в секунду

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

Убирает ли за собой

  • Нагрузочный прогон, который создаёт записи и оставляет их, изменит поведение следующего прогона.

Репрезентативно ли окружение

  • Результаты нагрузки, полученные в окружении с десятой частью данных, — это не прогноз, это просто число.

Корректность в реалистичных условиях

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

Терминал

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

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

Четыре вещи, от которых зависит, проживёт ли набор тестов API долго, — сессии, захваченные значения, порядок выполнения и очистка — описаны в документации по тестированию API.

Как честно читать результат нагрузочного теста

Результаты нагрузочных тестов перетолковывают чаще, чем почти любые другие результаты тестов, и обычно в двух направлениях.

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

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

Проверяйте корректность при каждом изменении

Нагрузочному тестированию место в расписании или перед релизом. Проверке корректности — в каждом пул-реквесте, потому что именно тогда регрессию дешевле всего исправить.

  • GitHub App — это вебхук, который вы настраиваете в панели TestSprite. Он слушает событие деплоя, которое ваш пайплайн уже генерирует, поэтому в репозитории ничего менять не нужно.

  • GitHub Actions встраивает этот шаг в ваш собственный workflow и настраивается из терминала.

Где TestSprite вписывается рядом с нагрузочным прогоном

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

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

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

Делает ли TestSprite нагрузочное тестирование?

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

Можно ли проверять тела ответов в нагрузочном тесте?

Большинство нагрузочных инструментов это поддерживают, но включают такую проверку немногие команды, потому что она стоит генератору пропускной способности. Делать это стоит на выборке запросов, а не на всех.

Что идёт первым?

Корректность. Нагрузочное тестирование эндпоинта, который возвращает неверные данные, даёт уверенную цифру ни о чём.

Как часто нужно проводить нагрузочное тестирование?

Перед релизами и после архитектурных изменений. Непрерывное нагрузочное тестирование стоит дорого и между этими точками редко сообщает что-то новое.

А нагрузочное тестирование в CI?

Нагрузочная проверка размером со smoke-тест вполне может работать. Полноценное тестирование пропускной способности в CI обычно означает либо бессмысленный уровень нагрузки, либо очень медленный пайплайн.

Коротко

Быстро и неправильно — это всё равно неправильно.

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