Про Тестинг
Ручное, автоматизированное, нагрузочное тестирование программного обеспечения
Процессы разработки ПО
четверг, 2 сентября 2010 г.
Модель нагрузки, как отправная точка при тестировании производительности
Введение
В настоящее время, с постоянно растущим числом интернет пользователей и пользователей ПК в общем, серьезно встает задача создания систем способных работать под колоссальными нагрузками без видимых замедлений и сбоев.
Любого рода проблемы связанные с плохой производительностью могут стать причиной отказа клиентов от использования Вашего программного обеспечения, даже если функционально оно их устраивало. В связи с этим, проведение качественного нагрузочного тестирования должно стать обязательным, для обеспечения стабильности работы ваших приложений.
Содержание
Что же такое нагрузочное тестирование?
Основные виды нагрузочных тестов:
Говоря ранее о качественном нагрузочном тестировании, я имел ввиду проведение полного цикла работ:
Далее в статье речь пойдет преимущественно о первом и на мой взгляд самом важном этапе – о разработке моделей нагрузки.
Примечание: Согласно некоторым данным этот этап может занимать до 50% времени по нагрузочному тестированию.
Разобьем работу над моделью нагрузки на несколько частей и определим, что необходимо будет делать на каждой из них:
А теперь более подробно рассмотрим каждый пункт, шаг за шагом.
Анализ требований
При анализе требований основной упор необходимо сделать на определение основных критериев успешности проведенных тестов. Для этого Вам необходимо будет выделить следующие характеристики:
А также некоторые метрики связанные с работой бизнес сценариев (например, количество бизнес операций в единицу времени, время выполнения бизнес операции и т.д.)
Заданные в требованиях характеристики, будут являться базовыми нагрузочными точками тестируемого приложения. Все получаемые результаты будут сравниваться с ними для принятия решения о завершении тестирования либо дальнейшем профилировании производительности.
Примечание: Основной проблемой при анализе требований будет являться их отсутствие! В связи с тем, что не всегда наши бизнес аналитики или люди ответственные за написание требований по производительности реально представляют как система должна работать под нагрузкой, какие именно требования должны быть предоставлены, очень часто цифры берутся просто «с потолка», поэтому нам приходится не только выделять имеющиеся требования, но и проводить их глубокий анализ на предмет их корректности.
Примечание: В случае, когда требования заданы не полностью, базовая нагрузочная точка может быть рассчитана по имеющимся данным (см. расчет нагрузочных точек), при условии наличия необходимых характеристик.
Примечание: Характеристика “Максимальное количество пользователей” на самом деле является малоинформативной, в случае если для тестирования нам необходимо будет работать с несколькими группами пользователей. Поэтому крайне важно будет знать более менее точное количество пользователей в каждой группе.
Анализ требований в зависимости от типа проекта
При анализе требований необходимо учесть разрабатывается ли новое (startup project) или же проект направлен на профилирование нагрузки для уже находящегося в эксплуатации приложения (profiling project).
Рассмотрим на основании чего разрабатываются требования по производительности в зависимости от типа проекта.
Для startup проектов:
Для profiling проектов:
И уже после получения всех данных из всех источников можно получить более менее точные требования по производительности для тестируемого приложения.
Примечание: В случае, если подобный анализ “имел место быть”, и в документации по проекту четко описаны все требования, то можно считать, что вам повезло. Так как в противном случае часть работы по разработке требований может лечь на Ваши плечи и будет включено во время отведенное на тестирование, которого и без того обычно не хватает.
Анализ целевой аудитории
Общение непосредственно с пользователями, наблюдение за их действиями, помогает нам более точно понять как будет происходить работа с ПО, какие части приложения наиболее критичны и требуют особого внимания.
Примечание: В случае, если тестируемая система уже находится в эксплуатации, пользовательские сценарии и распределенее запросов в течении дня, можно получить проанализировав логи приложения и сервера.
В результате мы получим:
Например: Утром операторы проверяют журналы посещения, обрабатывают сообщения клиентов, после обеда вводят новые товары в базу, и в конце рабочего дня снова анализируют журналы и сообщения. Значит основная нагрузка на журналы посещения и базы сообщений будет в начале и в конце рабочего дня.
Определение базового профиля нагрузки
Выделив, на предыдущем шаге группы пользователей, бизнес сценарии, требования к системе можем приступить к созданию профиля нагрузки – набор операций и интенсивность их выполнения для каждой пользовательской группы.
Зная количество пользователей в каждой группе, мы должны будем распределить их для выполнения требуемых операций, сохранив необходимую интенсивность.
Распределим выполнение операций следующим образом: 5 админов выполняют операцию добавления и 5 забанивают пользователей. Проведем перерасчет интенсивности выполнения операций:
В течении дня 10 администраторов добавляют 240 пользователей. Значит, интенсивность выполнения операции добавления для 1 администратора = 1 операция в час. Но в нашем случае только 5 админов будут выполнять операцию добавления, значит нам необходимо увеличить интенсивность так, чтобы количество добавленных пользователей осталось прежним. Итого, мы получим, что выполняя по 2 операции в час, 5 админов будут добавлять те же 240 пользователей. Проведя аналогичный перерасчет интенсивности для операции “забанить пользователя”, мы получим профиль нагрузки для группы Администраторы:
| группа | кол-во юзеров | операция | интенсивность опер./час |
|---|---|---|---|
| админы | 5 | добавить пользователя | 2 |
| админы | 5 | забанить пользователя | 5 |
Проведя аналогичный перерасчет для каждой группы пользователей, мы получим небольшую сводную таблицу со списком операций и интенсивностью их выполнения:
| группа | кол-во юзеров | операция | интенсивность опер./сек |
|---|---|---|---|
| админы | Z | добавить пользователя | N |
| админы | Z | забанить пользователя | N |
| . | |||
| покупатели | Z | вход/выход в систему | N |
| покупатели | Z | поиск товара | N |
| покупатели | Z | покупка товара | N |
| . | |||
| продавцы | Z | просмотр посещения | N |
| продавцы | Z | добавление/удаление/ товара | N |
Именно это таблица и будет являться полным базовым профилем нагрузки для тестируемого приложения.
Разработка моделей нагрузки
В зависимости от вида проводимого тестирования и целей преследуемых им, нам придется разрабатывать разные модели нагрузки.
Так разным может быть:
Проще всего изменения проводить, варьируя параметрами в базовом профиле нагрузки и инструменте для тестирования производительности (например, в HP LoadRunner Controller).
Модель тестирования производительности
Постепенное увеличение нагрузки, добавляя новых пользователей с некоторым интервалом времени, позволяет нам определить:
Модель стрессового тестирования
Увеличивая интенсивность операций выше пиковых (максимально разрешенных) значений либо увеличивая количество пользователей, до тех пор пока нагрузка не станет выше максимально допустимых значений, проверяем, что система работоспособна в условиях стресса. Далее, опустив нагрузку до средних значений, проверяем (способность системы к регенерации), что система вернулась к нормальному состоянию (основные нагрузочные характеристики не превышают базовые).
Модель объемного тестирования
Можно использовать ту же модель что и для тестирования производительности однако целью будет проверка работы системы с прогнозом на будущий рост объема данных. Следовательно одним и самым важным предусловием теста будет увеличение объемов базы данных приложения до требуемых размеров. Таким образом мы сможем проверить и оценить производительность, прогнозируя рост системы на год, два или три вперед.
Модель тестирования стабильности или надежности
Используя базовый нагрузочный профиль, запускаем тест длительностью от нескольких часов до нескольких дней, с целью выявления утечек памяти, перезапуска серверов и других аспектов влияющих на нагрузку.
Выводы
Четкое следование всем вышеописанным инструкциям по разработке моделей нагрузки, позволит нам:
Профиль мощности электроэнергии предприятия: снятие с прибора учета
Что такое профиль мощности?
С 1 июля 2013 года для всех крупных и средних предприятий и организации в России (потребителей с максимальной мощностью не менее 670 кВт), стало обязательным требование о выборе 3-6 ценовой категории электроэнергии для расчетов с поставщиком электрической энергии. Для расчетов по одной из указанной ценовых категорий, любому потребителю необходимо наличие установленных приборов учета электроэнергии, позволяющих хранить профиль мощности электроэнергии не менее 90 суток.
Кроме того, определение стоимости электроэнергии по всем потребителям, закупка электрической энергии для которых производится на оптовом рынке электроэнергии и мощности, осуществляется с применением профиля мощности.
Здесь можно скачать пример профиля мощности в таблице.
Таким образом, снятие и предоставление поставщику электроэнергии профиля мощности с установленного счетчика имеет очень важное значение для потребителя. Если он своевременно не будет исполнять свои обязательства по снятию профиля мощности с прибора учета, то это приведет в значительному увеличению стоимости электроэнергии.
Что такое макет XML 80020 и как снять профиль мощности с прибора учета?
Многие поставщики электроэнергии в договоре энергоснабжения предусматривают обязанность потребителя предоставлять профиль мощности по строго установленной форме макета (макет XML 80020).
Существует большое количество программного обеспечения, позволяющее считывать такие данные с прибора учета.
Снимать данные о почасовом потреблении электрической энергии и мощности за прошедший месяц возможно двумя способами:
1. «Вручную» с использованием ноутбука или иного мобильного устройства. Для этого на устройстве куда планируется выгружать данные со счетчика электроэнергии необходимо наличие предустановленного специализированного программного обеспечения (его можно бесплатно скачать на официальном сайте производителя прибора учета электроэнергии). Также необходимо устройство для организации связи ноутбука (мобильного устройства) и самого счетчика. Таким устройством может быть оптопорт. Сама процедура снятия профиля мощности у предприятия занимает очень короткое время и не является сложной. В интернете существует множество информации как необходимо осуществлять снятие профиля мощности.
2. «Удаленно» с использованием системы АИИС КУЭ или устройства передачи данных о показаниях. В этом случае, данные о почасовом потреблении электроэнергии (профиле мощности) поступают на сервер автоматически. Вам остается лишь отправить их в адрес поставщика электроэнергии.
Нагрузочное тестирование как CI-сервис для разработчиков
Одна из проблем, с которыми часто сталкиваются мультипродуктовые вендоры ПО, это дублирование компетенций инженеров — разработчиков, тестировщиков и администраторов инфраструктуры — почти в каждой команде. Это касается и дорогостоящих инженеров — специалистов в области нагрузочного тестирования.
Вместо того, чтобы заниматься своими прямыми обязанностями и использовать свой уникальный опыт для выстраивания процесса нагрузочного тестирования, выбирать методологию, оптимальные значения метрик и писать автотесты в соответствии с профилями нагрузки, инженерам зачастую приходится с нуля разворачивать тестовую инфраструктуру, настраивать инструменты нагрузки, самим встраивать их в CI-системы, настраивать мониторинг и публикацию отчетов.
Решения некоторых организационных проблем в тестировании, которые мы применяем в Positive Technologies, вы можете найти в другой статье. А в этой я расскажу про возможность интеграции нагрузочных тестов в общий CI-конвейер с помощью концепции «нагрузочное тестирование как сервис» (load testing as a service). Вы узнаете, как и какие докер-образы источников нагрузки можно использовать в CI-конвейере; как подключить источники нагрузки в свой CI-проект при помощи сборочного шаблона; как выглядит демопайплайн для запуска нагрузочных тестов и публикации результатов. Статья может быть полезной инженерам по тестированию ПО и инженерам-автоматизаторам в CI, кто задумался об архитектуре своей нагрузочной системы.
Суть концепции
Концепция load testing as a service подразумевает возможность интегрировать инструменты нагрузки Apache JMeter, Yandex.Tank и собственные фреймворки в произвольную систему continuous integration. Демопример будет для GitLab CI, но принципы изложены общие для всех CI-систем.
Load testing as a service — это централизованный сервис для проведения нагрузочного тестирования. Нагрузочные тесты запускаются в выделенных пулах агентов, публикация результатов происходит автоматически в GitLab Pages, Influx DB и Grafana или в системы тест-репортинга (TestRail, ReportPortal и т. п.). Автоматизация и масштабирование реализуются максимально просто — через добавление и параметризацию в проекте GitLab CI обычного шаблона gitlab-ci.yml.
Преимущество подхода заключается в том, что вся CI-инфраструктура, нагрузочные агенты, докер-образы источников нагрузки, пайплайны тестирования и публикация отчетов — поддерживаются силами централизованного отдела автоматизации (DevOps-инженерами), а инженеры по нагрузочному тестированию могут сосредоточить свои усилия на разработке тестов и анализе их результатов, не занимаясь инфраструктурными вопросами.
Для простоты описания будем считать, что целевое тестируемое приложение или сервер уже развернуты и настроены заранее (для этого могут быть использованы автоматизированные сценарии на Python, SaltStack, Ansible и др.). Тогда вся концепция нагрузочного тестирования как сервиса укладывается в три этапа: подготовка, тестирование, публикация отчетов. Подробнее на схеме (все картинки кликабельны):
Основные понятия и определения в нагрузочном тестировании
При проведении нагрузочных испытаний мы стараемся придерживаться стандартов и методологии ISTQB, используем соответствующую терминологию и рекомендуемые метрики. Приведу краткий перечень основных понятий и определений в нагрузочном тестировании.
Нагрузочный агент (load agent) — виртуальная машина, на которой будет запущено приложение — источник нагрузки (Apache JMeter, Yandex.Tank или самописный нагрузочный модуль).
Цель тестирования (target) — сервер или приложение, установленное на сервере, которое будет подвергаться нагрузке.
Тестовый сценарий (test case) — набор параметризованных шагов: действия пользователей и ожидаемые реакции на эти действия, с зафиксированными сетевыми запросами и ответами, в зависимости от заданных параметров.
Профиль или план нагрузки (profile) — в методологии ISTQB (п. 4.2.4, стр. 43) профили нагрузки определяют критически важные для конкретного теста метрики и варианты изменения параметров нагрузки в течение теста. Примеры профилей вы можете видеть на рисунке.
Тест (test) — сценарий с заранее определенным набором параметров.
Тест-план (test-plan) — набор тестов и профиль нагрузки.
Тестран (testrun) — одна итерация запуска одного теста с полностью выполненным сценарием нагрузки и полученным отчетом.
Сетевой запрос (request) — HTTP-запрос, отправляемый от агента к цели.
Сетевой ответ (response) — HTTP-ответ, отправляемый от цели к агенту.
HTTP-код ответа (HTTP responses status) — стандартный код ответа от сервера приложений.
Транзакция (transaction) — полный цикл «запрос — ответ». Транзакция считается от начала отправки запроса (request) до завершения приема ответа (response).
Статус транзакции (transactions status) — удалось ли успешно завершить цикл «запрос – ответ». Если в этом цикле была любая ошибка, то вся транзакция считается неуспешной.
Время отклика (latency) — время от окончания отправки запроса (request) до начала приема ответа (response).
Метрики нагрузки (metrics) — определяемые в процессе нагрузочного тестирования характеристики нагружаемого сервиса и нагрузочного агента.
Основные метрики для измерения параметров нагрузки
Некоторые наиболее общеупотребительные и рекомендуемые в методологии ISTQB (стр. 36, 52) метрики приведены в таблице ниже. Схожие метрики для агента и цели указаны в одной строке.
| Метрики для нагрузочного агента | Метрики целевой системы или приложения, тестируемых под нагрузкой |
|---|---|
| Количество vCPU и памяти RAM, Disk — «железные» характеристики нагрузочного агента | CPU, Memory, Disk usage — динамика загрузки процессора, памяти и диска в процессе тестирования. Обычно измеряется в процентах от максимально доступных значений |
| Network throughput (on load agent) — пропускная способность сетевого интерфейса на сервере, где установлен нагрузочный агент. Обычно измеряется в байтах в секунду (bps) | Network throughput(on target) — пропускная способность сетевого интерфейса на целевом сервере. Обычно измеряется в байтах в секунду (bps) |
| Virtual users— количество виртуальных пользователей, реализующих сценарии нагрузки и имитирующих реальные действия пользователей | Virtual users status, Passed/Failed/Total — количество успешных и неуспешных статусов работы виртуальных пользователей для сценариев нагрузки, а также их общее количество. |
Обычно ожидается, что все пользователи смогли выполнить
все свои задачи, указанные в профиле нагрузки.
Любая ошибка будет означать, что и реальный пользователь не сможет
решить свою задачу при работе с системой
Важная характеристика нагрузочного агента: сколько он может генерировать запросов.
Фактически это имитация обращения к приложению виртуальными пользователями
— количество сетевых ответов в секунду (или минуту).
Важная характеристика целевого сервиса: сколько удалось
сгенерировать и отправить ответов на запросы с
нагрузочного агента
от сервера приложения, полученных нагрузочным агентом.
Например, 200 OK означает успешное обращение,
а 404 — что ресурс не обнаружен
отправки запроса (request) до начала приема ответа (response).
Обычно измеряется в миллисекундах (ms)
завершение цикла «запрос — ответ».
Это время от начала отправки запроса (request)
до завершения приема ответа (response).
Для реальных пользователей неуспешная
транзакция фактически будет означать
невозможность работать с системой под нагрузкой
Принципиальная схема нагрузочного тестирования
Принципиальная схема нагрузочного тестирования очень проста и состоит из трех основных этапов, о которых я уже упоминал: Prepare — Test — Report, то есть подготовка целей тестирования и задание параметров для источников нагрузки, затем выполнение нагрузочных тестов и, в конце, формирование и публикация отчета о тестировании.
Примечания к схеме:
Классификатор сущностей, этапов и шагов на схеме
| Этапы и шаги | Что происходит | Что на входе | Что на выходе |
|---|---|---|---|
| Prepare: этап подготовки к тестированию | |||
| LoadParameters | Задание и инициализация пользователем параметров нагрузки, выбор метрик и подготовка тест-плана (профиля нагрузки) | Пользовательские параметры для инициализации агента нагрузки Тест-план Цель тестирования | |
| VM | Развертывание в облаке виртуальной машины с требуемыми характеристиками | Параметры ВМ для агента нагрузки Скрипты автоматизации для создания ВМ | Настроенная ВМ в облаке |
| Env | Настройка ОС и подготовка окружения для работы нагрузочного агента | Параметры окружения для агента нагрузки Скрипты автоматизации для настройки окружения | Подготовленное окружение: ОС, сервисы и приложения, необходимые для работы агента нагрузки |
| LoadAgents | Установка, настройка и параметризация нагрузочного агента. Или скачивание докер-образа с преднастроенным источником нагрузки | Докер-образ источника нагрузки (ЯТ, JM или самописный фреймворк) Параметры настройки агента нагрузки | Настроенный и готовый к работе агент нагрузки |
| Test: этап выполнения нагрузочных тестов. Источниками являются агенты нагрузки, развернутые в выделенных пулах агентов для GitLab CI | |||
| Load | Запуск агента нагрузки с выбранным тест-планом и параметрами нагрузки | Пользовательские параметры для инициализации агента нагрузки Тест-план Цель тестирования | Логи выполнения нагрузочных тестов Системные журналы Динамика изменения метрик цели и нагрузочного агента |
| RunAgents | Исполнение агентом нагрузки тестовых сценариев в соответствии с профилем нагрузки Взаимодействие агента нагрузки с целью тестирования | Тест-план Цель тестирования | |
| Logs | Сбор «сырых» логов в процессе нагрузочного тестирования: записи о действиях агента нагрузки, состоянии цели тестирования и ВМ, на которой запущен агент | Логи выполнения нагрузочных тестов Системные журналы | |
| Metrics | Сбор «сырых» метрик в процессе тестирования | Динамика изменения метрик цели и нагрузочного агента | |
| Report: этап подготовки отчета о тестировании | |||
| Generator | Обработка собранных нагрузочной системой и системой мониторинга «сырых» метрик и логов Формирование отчета в человекочитаемом виде, возможно с элементами аналитики | Логи выполнения нагрузочных тестов Системные журналы Динамика изменения метрик цели и нагрузочного агента | Обработанные «сырые» логи в формате, пригодном для выгрузки во внешние хранилища Статический отчет о нагрузке, пригодный для анализа человеком |
| Publish | Публикация отчета о нагрузочном тестировании во внешнем сервисе | Обработанные «сырые» логи в формате, пригодном для выгрузки во внешние хранилища | Сохраненные во внешнем хранилище отчеты о нагрузке, пригодные для анализа человеком |
Подключение источников нагрузки в CI-шаблоне
Перейдем к практической части. Я хочу показать, как на некоторых проектах в компании Positive Technologies мы реализовали концепцию нагрузочного тестирования как сервиса.
Сначала силами наших DevOps-инженеров мы создали в GitLab CI выделенный пул агентов для запуска нагрузочных тестов. Чтобы не путать их в шаблонах с другими, например сборочными, пулами, мы добавили теги на эти агенты, tags: load. Можно использовать любые другие понятные теги. Они задаются во время регистрации GitLab CI Runners.
Как узнать требуемую мощность по «железу»? Характеристики нагрузочных агентов — достаточное количество vCPU, RAM и Disk — могут быть рассчитаны исходя из того, что на агенте должны быть запущены Docker, Python (для Yandex.Tank), агент GitLab CI, Java (для Apache JMeter). Для Java под JMeter также рекомендуют использовать минимум 512 МБ RAM и, в качестве верхнего предела, 80% доступной памяти.
Таким образом, исходя из нашего опыта, мы рекомендуем использовать для нагрузочных агентов как минимум: 4 vCPU, 4 ГБ RAM, 60 ГБ SSD. Пропускная способность сетевой карты определяется на основе требований профиля нагрузки.
У нас в основном используются два источника нагрузки — докер-образы Apache JMeter и Yandex.Tank.
Yandex.Tank — это опенсорсный инструмент компании Yandex для проведения нагрузочного тестирования. В основе его модульной архитектуры — высокопроизводительный асинхронный hit-based-генератор HTTP-запросов Phantom. Танк имеет встроенный мониторинг ресурсов тестируемого сервера по протоколу SSH, может автоматически остановить тест по заданным условиям, умеет выводить результаты как в консоль, так и в виде графиков, к нему можно подключить свои модули для расширения функциональности. Кстати, мы использовали Танк, когда это еще не было мейнстримом. В статье «Яндекс.Танк и автоматизация нагрузочного тестирования» можно прочитать историю, как в 2013-ом мы проводили с его помощью нагрузочное тестирование PT Appllication Firewall — одного из продуктов нашей компании.
Apache JMeter — это опенсорсный инструмент для проведения нагрузочного тестирования компании Apache. Он может одинаково хорошо использоваться как для тестирования статических, так и динамических веб-приложений. JMeter поддерживает огромное количество протоколов и способов взаимодействия с приложениями: HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET и т. д.), SOAP / REST Webservices, FTP, TCP, LDAP, SMTP(S), POP3(S) и IMAP(S), базы данных через JDBC, умеет исполнять shell-команды и работать с Java-объектами. У JMeter есть IDE для создания, отладки и исполнения тест-планов. Также имеется CLI для работы в командной строке любой совместимой с Java ОС (Linux, Windows, Mac OS X). Инструмент умеет динамически генерировать HTML-отчет о тестировании.
Для удобства использования внутри нашей компании, для возможности самим тестировщикам изменять и добавлять окружение мы сделали сборки докер-образов источников нагрузки на GitLab CI с публикацией во внутренний докер-реджистри на Artifactory. Так получается быстрее и проще подключать их в пайплайнах для нагрузочных тестов. Как сделать docker push в registry через GitLab CI — смотрите в инструкции.
Базовый докер-файл для Yandex.Tank мы взяли этот:
А для Apache JMeter этот:
Шаблон и пайплайн
Шаблон очень простой и демонстрирует три этапа нагрузочного тестирования, описанных выше на схеме: подготовка, тестирование и публикация отчетов. За это отвечают stages: Prepare, Test и Report.
Apache JMeter умеет сам формировать HTML-отчет, поэтому его выгоднее сохранять в GitLab Pages штатными средствами. Вот так выглядит отчет Apache JMeter:
Резюме
P. S. Хочу сказать большое спасибо моим коллегам, Сергею Курбанову и Николаю Юсеву, за техническую помощь с реализацией концепции load testing as a service в нашей компании.
Автор: Тимур Гильмуллин — зам. руководителя отдела технологий и процессов разработки (DevOps) компании Positive Technologies
