Как мы научили ручных тестировщиков и аналитиков проводить нагрузочное тестирование сервисов

Привет, меня зовут Денис Свиридов, я занимаюсь автоматизацией тестирования в Hoff Tech. Мы активно разрабатываем микросервисы для сети мебельных гипермаркетов Hoff и естественным образом пришли к необходимости проведения нагрузочного тестирования по ним. В таком тестировании мы видим один из обязательных шагов для улучшения качества создаваемых IT-решений.

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

С другой стороны, в штате совсем немного тестировщиков-автоматизаторов, которые могут разрабатывать нагрузочные тесты.

И как выйти из ситуации: нагрузочных тестов надо проводить все больше и больше, а специализированных тестировщиков-автоматизаторов неизменное количество? Наша задумка была не нова: разработать Low-code решение, чтобы сотрудники без особых знаний программирования и без привлечения автоматизаторов могли проводить нагрузочное тестирование своих сервисов. В этой статье я расскажу о том, что у нас получилось с технической и организационной точек зрения.

aac1f3e2e1209b87a0ed28ff95f7e5fa.png

Техническое описание решения

Схема решения

Схема Low-code решения

Схема Low-code решения

Для запуска тестов мы выбрали CI/CD-систему Jenkins: у нее удобный визуальный интерфейс, множество плагинов, и сотрудники могут работать с ней без каких-либо навыков программирования.

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

Использование Low-code решения без программирования

Первый вариант использования прост — с помощью Excel и json. В Yandex.Tank при такой схеме используется генератор нагрузки (пушка) Phantom. Для запуска аналитик или тестировщик формирует:

Так выглядит пример конфигурационного yaml-файла:

host: api.test.ru:443
endpoints:
  - title: 1 json
    endpoint: /v1/item/bonus
    json_file: bonus1.json
  - title: 2 json
    endpoint: /v1/item/bonus
    json_file: bonus2.json

method: POST
ssl: True
timeout: 1000
ammount_rps: $AMMOUNT_RPS|30
load_type: $LOAD_TYPE|rps
rps_type: $RPS_TYPE|const(1, 10s)
instances: $INSTANCES|5

Написанное на Python Low-code решение запускается как Jenkins-джоб. Он считывает параметры из конфигурационного yaml-файла, и на основании таблицы Excel по шаблону из параметра json_file формируется список json«ов для каждого эндпоинта из параметра endpoint. Список json«ов складывается в один текстовый файл (патрон).

В подготовленном Excel-файле для некоторых типов данных допускается указывать не фиксированные значения, а генерировать произвольные, используя специальные ключевые слова. Пример можно увидеть в на рисунке  в строках 5–8.

Пример Excel-файла для проведения нагрузочного тестирования 

Пример Excel-файла для проведения нагрузочного тестирования 

После этого Jenkins-джоб конфигурирует Yandex.Tank, подкладывает ему сформированный файл-патрон и запускает нагрузочное тестирование. Результаты тестирования публикуются в сервисе Overload.yandex.net.

Использование Low-code решения с минимальными навыками программирования

Второй вариант использования немного сложнее — через написание сценариев на Python. В Yandex.Tank для этого используется другой генератор нагрузки (пушка) — BFG. Чтобы не-разработчику было проще написать такой скрипт, автотестеры могут подсказать примеры кода на Python, подходящие под задачу.

Пример конфигурационного yaml-файла для такого варианта:  

engine: bfg
host: api.test.ru
instances: $INSTANCES|5
bfg_loop: $LOOP|10
class_name: LoadTestingScenario
module_name: scenarios_service
load_type: $LOAD_TYPE|rps
rps_type: $RPS_TYPE|const(10, 10s)

Jenkins-джоб через наше решение запускает Yandex.Tank, передавая Python-скрипт, указанный в параметре module_name с указанием класса class_name как точки запуска. Далее Yandex.Tank выполняет сценарий нагрузочного тестирования,   прописанный в классе class_name. Результаты тестирования публикуются в сервисе Overload.yandex.net.

Настройка джоба Jenkins

Предварительно был подготовлен эталонный Jenkins-джоб. Любой, кто хочет создать свой нагрузочный тест, копирует эталонный джоб и заполняет пару полей.

Обязательные параметры джобы в Jenkins 

Обязательные параметры джобы в Jenkins 

При создании джоба необходимо заполнить поля SERVICE_FOLDER (сетевой путь до Python-скриптов или Excel-файлов) и SERVICE_NAME (здесь указывается конфигурационный yaml-файл со всей информацией для запуска нагрузочного теста).

Настройкой графика запуска и самим запуском джоба занимается другой человек — ответственный автоматизатор-тестировщик, а не автор теста. Я расскажу об этом позже. Это краткое техническое описание решения. Код Low-code решения можно найти в нашем GitHub. 

Теперь про процесс со стороны организации взаимодействия людей.

Организация процесса нагрузочного тестирования

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

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

Описание задачи в Jira

Под каждый нагрузочный автотест создается новая задача в Jira, которая станет документацией по нему. В задаче автор описывает:

  • тест-кейс, на котором будет выполняться нагрузочное тестирование;

  • профиль нагрузки;

  • модель нагрузки.

Заполнить задачу надо определенным образом:  

Поле

Правило

Проект 

Указывается Jira-проект, в рамках которого создается нагрузочный тест.

Это же определяет, за чей счет выполняется разработка нагрузочного теста

Тип задачи

Тест-кейс

Тема

Название нагрузочного сценария

Метки

«нагрузочное_тестирование» 

Компонент

Компонент проставляется обязательно, например, мы ставим AutoTest,  LoadTest.

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

Описание

Описывается подробно профиль нагрузочного тестирования сервиса

Вложения

Шаблоны Json, Excel-файлы, Python-скрипты

Шаги тест-кейса

В шагах тест-кейса прописываются проанализированные и сформированные модели нагрузочного тестирования.

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

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

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

Например: количество пользователей и интенсивность запросов, варианты параллельной работы пользователей (последовательно, ступенчато группами, запуск всех сразу), длительность работы сценария.

Организация Jenkins-пространства

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

Структура папки LoadTesting в Jenkins 

Структура папки LoadTesting в Jenkins 

Настройка Jenkins-джоба под нагрузочный тест

После описания тест-кейса в Jira автор, составивший нагрузочный тест, выбирает один из вариантов реализации на базе нашего Low-code решения: упрощенный без программирования или посложнее, с Python-скриптом.

Далее составляется Excel-файл либо Python-скрипт, а к ним — конфигурационный yaml-файл.

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

Наше Low-code решение снижает порог вхождения в мир тестирования, а значит автор, возможно, не сможет предсказать последствия тестирования для IT-инфраструктуры. Поэтому до запуска нагрузочного теста ответственный тестировщик-автоматизатор проводит ревью модели нагрузки, которую заказали. Это важный этап процесса, которым мы стараемся защитить тестируемые IT-системы от «аппетитов» автора нагрузочного теста.

Также мы разграничили права доступа на настройку запуска Jenkins-джобов. Пользователи в роли QA могут создать Jenkins-джоб, но не могут настроить расписание его выполнения. Право запуска отдается ролям admin и developer. Эти разграничения мы сделали через плагин Role-based Authorization Strategy.

Настройка доступа для ролей в Jenkins в плагине Role-based Authorization Strategy

Настройка доступа для ролей в Jenkins в плагине Role-based Authorization Strategy

Запуск нагрузочного теста

Перед запуском настроенного нагрузочного теста необходимо выполнить еще несколько условий:

  • первый запуск с новыми параметрами модели нагрузки должен проходить только на тестовом или предрелизном контуре, даже если согласовали  провести нагрузочное тестирование на рабочем контуре. Это минимизирует потенциальный вред для рабочей ИТ-системы в случае возникновения ошибок или проблем;

  • перед запуском автор нагрузочного теста должен предупредить коллег отдела тестирования и DevOps-инженеров. Это позволит им подготовиться к возможным непредвиденным ситуациям и быстро отреагировать на них в случае необходимости.

Эти условия важны для обеспечения безопасности и качества процесса тестирования, а еще для минимизации возможных рисков.

В финале Jenkins-джоб выполняется, а данные с результатами сохраняются в Overload.yandex.net.

Анализ результатов нагрузочного тестирования

После тестирования проводится анализ результатов в сервисе Overload.yandex.net, а сотрудник заполняет карточку результатов по каждому эндпоинту сервиса. Результаты нагрузочного тестирования фиксируются в таблицы, из которых команда понимает, что заявленный уровень качества IT-решения с точки зрения производительности и устойчивости достигнут.

Результаты теста, подтверждающие достижение требуемых показателей:

План

Факт

RPS, количество запросов в секунду

100

100

Длительность теста

-

10 минут

Процент успешных ответов

-

100%

Кол-во ответов с ошибкой

-

0

TTFB*

Среднее

100 мс

100 мс

Минимальное

-

86 мс

Максимальное

-

122 мс

 * TTFB — time-to-first-byte — время между запросом к сервису и временем начала получения ответа от него

Результаты теста, иллюстрирующие предельно допустимую нагрузку:

e5314931e09d162801847b1e52e3a261.png

Результаты теста стабильности:

27c811ade7ba91a6d8d481dc9043120c.png

Ревизия списка Jenkins-джобов

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

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

Заключение

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

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

В итоге мы расширили рабочий инструментарий проектных команд, чтобы они выпускали устойчивые и надежные IT-системы без значительных затрат.

© Habrahabr.ru