Что такое performance testing
Мы не ищем баги: что такое нагрузочное тестирование
Как узнать, не превратится ли ваш интернет-магазин в тыкву во время «чёрной пятницы» — когда трафик вырастет в 10 раз.
кадр из фильма «Зомби по имени Шон»
Давид Нариманидзе
Taode01 в Twitter. 28 лет. Полтора года в нагрузочном тестировании, куда перекатился из системного администрирования и любительской разработки мобильных приложений. В абсолютном восторге от работы, потому что это редкая возможность спасать компанию от лишних трат, а клиентов — от расходования совсем не казённых нервов. Да ещё и практически неограниченно развиваться самому: во время работы в НТ приходится и код писать, и железо подбирать, и взаимодействовать с большим количеством клёвых специалистов из других отделов.
Нагрузочное тестирование (НТ) — один из тестов производительности. От любой системы требуется быстро и правильно отвечать на запросы пользователей: и если правильность ответов относится скорее к функциональному тестированию, скорость является как раз заботой специалистов по нагрузочному тестированию. Однако формулировка «система должна отвечать быстро» — слабое требование.
Мне нравится определение из блога Miro на «Хабре»: «Нагрузочное тестирование — это тип тестирования, в котором мы проверяем, соответствует ли наша система поставленным нефункциональным требованиям к производительности при работе под высокой нагрузкой в различных сценариях».
В основе статьи — Twitter-тред автора.
Какими бывают нагрузочные тесты
Начнём с того, какие бывают виды тестирования. У каждого инженера есть мнение на этот счёт, поэтому и я поделюсь своим 🙂 Я разделяю тесты на функциональные, нефункциональные и связанные с изменениями.
Функциональное тестирование. В него входит проверка безопасности и взаимодействия — мы испытываем систему и осознанно бьём по её слабым местам, убеждаемся, что она выполняет все функции, которые были прописаны в ТЗ.
Нефункциональное тестирование (НФ). Определяет характеристики ПО, которые измеряются в каких-то конкретных величинах. В первую очередь на таких тестах изучают производительность системы — проводят нагрузочное и стрессовое тестирование, исследуют стабильность и работу с большими базами данных. А после этого проверяют настройки, отказоустойчивость и восстановление системы, ищут способы увеличить её производительность. Тестирование производительности помогает узнать, как меняются стабильность и быстродействие системы под разной нагрузкой, а также проверить её масштабируемость, надёжность и уточнить, сколько ресурсов она будет использовать.
Вид НФ-теста | На какие вопросы отвечает |
---|---|
Нагрузка | Соответствует ли нефункциональным требованиям система |
Стабильность | Надёжно ли работает система в течение продолжительного времени |
Отказоустойчивость | Сможет ли система сама переместиться на другой сервер, если откажет основной |
Восстановление | Как быстро система восстановится после сбоя |
Стресс | Что случится при незапланированной нагрузке |
Объём | Как будет работать проект, если база данных вырастет в 100 раз |
Масштабируемость | Как будет увеличиваться нагрузка на компоненты системы с ростом числа пользователей |
Потенциал | Сколько пользователей могут работать в системе одновременно |
Конфигурация | Как заставить систему работать быстрее |
Сравнение | Какое оборудование и ПО выбрать |
Тесты, связанные с изменениями. К этой категории относятся:
Как составить методику нагрузочного тестирования
Методика нагрузочного тестирования (МНТ) — почти как Библия для нагрузочника. Это документ, в который необходимо вписать всё, что может случиться на проекте, учесть максимальное число сценариев и результаты тестов.
Чтобы обезопасить себя от факапов, в методике нужно сразу прописать значения всех терминов, чтобы потом не возникло недопонимания, которое обычно приводит к судам и нервотрёпке.
Я разрабатываю методику нагрузочного тестирования по такой структуре:
1. Информация о проекте и определения терминов.
2. Цели тестирования. Например, «внедрить в программу новую фичу» или «подготовить интернет-магазин к распродаже, когда пользователей на сайте будет в X раз больше».
3. Ограничения нагрузочного тестирования. Это не функциональное тестирование, а значит, мы намеренно не ищем баги и не оцениваем внешние системы, потому что нас наняли на проверку только одной.
У меня заглушки и эмуляторы работают на Java, скрипты я пишу в HP LoadRunner, а запускаю в Performance Center.
5. Причины ошибочных результатов. Пишем, что неправильный пейсинг — время задержки между сценариями — приведёт к некорректным данным тестов.
6. Раздел с описанием тестового стенда. Это схемы с серверами, заглушками и генераторами нагрузки.
7. Таблица с требованиями к железу.
8. Таблица отличий стенда от системы на продакшене.
9. Стратегия тестирования.
10. Описание видов тестирования.
11. Требования к производительности от заказчика.
12. Моделирование нагрузки.
13. Профиль (который мы получаем от аналитиков или собираем на основе бизнес-прогнозов).
15. Стоимость внезапного изменения требований к проекту. Это избавит исполнителя и заказчика от лишних забот.
16. Материалы для сдачи проекта, куда входит всё, что мы подготовили для следующего специалиста.
Зачем всё это?
Если заказчик ничего не знает о конкретном тестировании, методика ответит на все его вопросы. В ней объясняется, за что компания платит деньги подрядчику и какие результаты получит на выходе.
В МНТ можно дать определение максимальной производительности. Мы пишем, что выполним серию тестов и пошагово будем увеличивать нагрузку до предельной, а в конце сделаем контрольную проверку и выясним показатели производительности.
Стратегия заканчивается выводами и списком критериев успешного завершения НТ. В выводы включаются данные, которые мы получили в результате мониторинга, общее заключение и список успешно проведённых тестов.
Как проводят нагрузочное тестирование
Чтобы провести нагрузочные тесты новой системы, я использую такой чек-лист:
ПО для НТ
Для проведения нагрузочного тестирования необходимо специфическое ПО.
Я лично работаю с HP LoadRunner, ещё есть ПО Gatling, Apache JMeter, BlazeMeter, LoadNinja и даже отечественный «Яндекс.Танк». У каждого из них есть свои плюсы и минусы: одни не работают со специфическими протоколами, другие бесплатны, третьи больше дружат с тяжёлыми скриптами и так далее.
Почему я использую LoadRunner? С одной стороны, он ориентирован на энтерпрайз-приложения — и это влияет на ценообразование, он очень дорогой. Да, пару десятков вьюзеров вы, конечно, сможете прогнать бесплатно, но этого не хватит для полноценного НТ, в котором используются сотни и тысячи виртуальных пользователей.
Зато LoadRunner позволяет тестировщикам ПО проводить комплексную оценку производительности своей системы. Его фишка — выявление узких мест ещё до того, как приложение будет внедрено или развёрнуто. В результате пользователи могут оценить каждый компонент по отдельности — даже прежде, чем он начнёт работать.
Выводы
Заглушка — часть кода, которая на время теста заменяет другой компонент, например сторонний API. Она отдаёт системе черновые данные.
Эмулятор — программная симуляция физического устройства. С ними на компьютере можно тестировать приложения для мобильных или других девайсов.
Средства виртуализации позволяют запустить на одном железе несколько независимых систем с нужными настройками. Например, это помогает тестировать Windows-приложения в среде Linux.
Нагрузочное тестирование на Gatling — Полное руководство. Часть 1
Эта статья представляет собой полное, подробное и исчерпывающее руководство по эффективному использованию Gatling для нагрузочного тестирования. Вы также можете ознакомиться с моими видеоуроками по Gatling на YouTube, где я более подробно раскрываю эту тему.
Краткий обзор руководства
Первый раз слышите о Gatling? Тогда для начала уделите внимание моей вводной статье о Gatling. Но если в двух словах:
Простой и выразительный DSL, который предлагает Gatling, упрощает написание скриптов нагрузочного тестирования.
Он не содержит графического интерфейса (например, как JMeter), хотя поставляется с графическим интерфейсом для облегчения записи скриптов.
Он может обрабатывать огромный объем трафика на одном компьютере, устраняя необходимость в сложной распределенной инфраструктуре тестирования.
Проверку кода с помощью Gatling можно встроить в систему контроля версий и легко использовать в связке с инструментами непрерывной интеграции для запуска нагрузочных тестов и тестов производительности как части вашей CI-сборки.
Что такое тестирование производительности?
Прежде чем мы начнем, давайте вкратце разберемся, что такое тестирование производительности (performance testing).
Приложение часто работает нормально, когда активна лишь часть пользователей. Но когда количество пользователей внезапно увеличивается, могут возникать проблемы с производительностью. Тестирование производительности направлено на выявление (и, в конечном итоге, решение) этих потенциальных проблем.
Существует несколько различных типов тестирования производительности, такие как:
Gatling подходит для всех этих подвидов тестирования производительности.
Вот некоторые из метрик, которые вы можете собрать во время тестирования производительности:
Это исчерпывающее учебное руководство по нагрузочному тестированию на Gatling, разделенное на несколько разделов. Если вы новичок в нагрузочном тестировании на Gatling, я бы рекомендовал вам ознакомиться с каждый из разделов по порядку.
Исходный код
Вы можете найти весь исходный код из этого руководства в моем репозитории на Github.
1. Установка Gatling
Прежде чем начать что-либо делать, убедитесь, что у вас установлен JDK8 (или более новый). Если вам нужна помощь с этим, ознакомьтесь с этим руководством по установке JDK.
Download Gatling
Разархивируйте архив в любое место на вашем компьютере. Откройте полученную папку и перейдите в каталог bin. Оттуда запустите:
После окончания загрузки Gatling вам будет предложено выбрать симуляцию для запуска:
Choose Gatling Simulation to run
Gatling запустит выбранный вами скрипт, который выполнит базовый нагрузочный тест на тестовом сайте Gatling с базой данных компьютеров.
2. Gatling Recorder
Можно, конечно, запускать скрипты, поставляемые с Gatling, но, несомненно, вы захотите разработать скрипты под ваше собственное приложение.
Как только вы овладеете Gatling (к концу этого руководства!), вы сможете писать скрипты с нуля в своей IDE или даже просто в текстовом редакторе.
Но прежде чем заняться этим, для начала вам будет проще использовать встроенный Gatling Recorder для записи вашего пользовательского пути (user journey).
2.1 Создание HAR-файла
Самый удобный способ использования Gatling Recorder, как мне кажется, предполагает генерацию HAR-файла (Http-архива) вашего пользовательского пути в Google Chrome.
Создание этих файлов и их импорт в Gatling Recorder позволяет обойти проблемы с записью на HTTPS.
Чтобы создать HAR-файл, выполните следующие действия:
Откройте Chrome Developer Tools и перейдите на вкладку Network.
Кликните Clear, чтобы удалить все предыдущие сетевые вызовы, а затем убедитесь, что красная кнопка записи включена.
Теперь перейдите в свою папку bin Gatling (в которой вы впервые запустили Gatling в предыдущем разделе) и запустите файл recorder.sh в Mac/Unix или recorder.bat в Windows. Загрузится Gatling Recorder.
В разделе HAR File перейдите к местоположению HAR-файла, созданного на шаге 5.
Все остальное оставьте как было по умолчанию и кликните Start!
Если все сработает так, как должно, вы увидите сообщение, что все прошло успешно.
3. Настройка проекта Gatling
Итак, теперь, когда вы получили представление о том, как выглядит скрипт Gatling (и как с ним запустить нагрузочный тест), давайте приступим к настройке среды для создания наших скриптов. Первое, что нам нужно выбрать, это IDE:
3.1 Выберите IDE для создания скриптов нагрузочного тестирования на Gatling
Хотя вы вполне можете создавать скрипты Gatling в любом текстовом редакторе, гораздо проще (и эффективнее) делать это в IDE. В конце концов, мы будем писать код Scala. Scala работает поверх JVM, поэтому любая IDE, поддерживающая JVM, должна нам подойти.
У вас есть несколько вариантов:
Вы можете использовать Eclipse, очень популярную Java IDE. В последнее время я почти не использовал Eclipse в работе, поэтому лучше ознакомьтесь с этой статьей как настроить и запустить тесты Gatling на Eclipse, если вы хотите пойти по этому пути.
Теперь, когда мы выбрали нашу IDE, нам понадобится система сборки, которая будет сочетаться с ней:
3.2 Выберите систему сборки для Gatling
Конечно, вы можете использовать Gatling без системы сборки и просто запускать его из первичных zip-файлов (как мы делали в первом разделе). Но есть вероятность, что вскоре вы все-таки захотите использовать систему сборки в своем проекте нагрузочного тестирования Gatling. Это упростит обслуживание в системе контроля версий. Опять же, у вас есть несколько вариантов на выбор:
Вы можете использовать Gradle, чрезвычайно популярную систему сборки. Как ни странно, Gatling не предоставляет официального плагина для Gradle, поэтому я рекомендую плагин Gradle для Gatling от lkishalmi. Ознакомьтесь с моей статьей Запускаем Gatling из Gradle — Полное руководство для начинающих, если вам нужна помощь в настройке.
Я расскажу о настройке нового проекта в IntelliJ Idea с Maven в оставшейся части этого раздела.
3.3 Создание проекта Gatling из архетипа Maven
Откройте терминал или командную строку и введите:
В конце, вы увидите этот запрос:
Затем вы должны увидеть:
Просто введите 1 для выбора архетипа Gatling. На следующем экране выберите последнюю версию:
Choose Gatling Version
На стартовой странице IntelliJ выберите Import Project.
Import IntelliJ Gatling project
После того, как импорт проекта будет завершен, откройте панель Project Directory слева и раскройте папку src>test>scala. Дважды кликните по классу Engine.scala. Вы можете увидеть сообщение No Scala SDK in module вверху экрана. Если это так, нажмите Setup Scala SDK:
Import Scala SDK in IntelliJ
Проверьте, какие версии Scala у вас есть:
Scala versions in IntelliJ
Если у вас нет версии, указанной здесь, кликните Create, выберите версию 2.12 и кликните кнопку download:
В качестве альтернативы, если у вас возникли проблемы с загрузкой бинарников Scala через IntelliJ, вы можете вместо этого загрузить бинарники Scala непосредственно со Scala-lang. Кликните Download the Scala binaries, как показано на этом скриншоте:
Download Scala binaries from Scala-lang
Сохраните бинарники где-нибудь на жестком диске и распакуйте ZIP-архив. Вернувшись в IntelliJ, снова кликните Setup Scala SDK, и на этот раз кликните Configure. Нажмите кнопку Add в левом нижнем углу:
Add the Scala binaries to IntelliJ
Перейдите в папку, которую вы только что загрузили и распаковали, и выберите папку lib:
Select the Lib folder to import Scala Binaries
Теперь в диалоге Add Scala Support вы сможете выбрать библиотеку Scala, которую вы загрузили:
Add Scala Support
Mark Test Sources as Root in IntelliJ
На всякий случай также отметьте всю папку src как source root:
Mark Sources Root
Наконец, кликните правой кнопкой мыши объект Engine и выберите Run:
Run the Engine Object in IntelliJ
3.4 Добавление базового скрипта Gatling
Чтобы протестировать нашу новую среду разработки, давайте добавим базовый скрипт Gatling. Этот скрипт запустит тест на базе данных компьютеров Gatling.
Примечание: В оставшейся части этого руководства мы будем писать Gatling-тесты для пользовательского приложения, которое я создал для этого туториала. Сейчас же я просто хотел продемонстрировать простой скрипт для базы данных компьютеров Gatling, чтобы мы могли проверить, правильно ли настроена наша среда.
В преддверии старта курса «Нагрузочное тестирование» приглашаем всех желающих записаться на бесплатный демо-урок в рамках которого рассмотрим интерфейс LoadRunner Virtual User Generator, запишем скрипт тестирования web-сайта, проведём его отладку и параметризацию. В результате вы научитесь создавать скрипты нагрузочного тестирования web-сайтов.
Обзор инструментария для нагрузочного и перформанс-тестирования
Как говорят иные отважные люди: «От dev до prod — всего один шаг». Люди опытные добавляют, что шаг этот называется «тестирование», причём самое разнообразное, и нам просто нет смысла им не верить.
Конечно, говоря о тестировании, нужно понять, с чем и за что мы боремся. Мы сознательно ограничили себя и решили сегодня поговорить исключительно про нагрузочное тестирование и тестирование производительности: темы, полярно удалённые друг от друга, крайне интересны в самом практическом выражении. Рассмотрим инструменты для того и другого, не привязываясь к какому-то конкретному стеку технологий, так что не удивляйтесь соседству Яндекс.Танк и BenchmarkDotNet!
Нагрузочное тестирование
Представим, что мы с вами написали некий сервис — теперь нужно понять, какую нагрузку он выдержит. Старая грустная шутка разработки качественного ПО гласит, что лучше иметь софт, который работает гарантированно плохо, чем софт, работающий хоть и хорошо, но негарантированно хорошо: в первом случае мы хотя бы будем знать, на что твёрдо можем рассчитывать. Далее, если наш сервис умеет масштабироваться тем или иным образом, то нужно понять, насколько с ростом нагрузки масштабирование оказывается полезным и выполняет ли оно возложенные на него проектом задачи.
Что ж, берём и направляем на наше детище нагрузку, притом внимательно наблюдая за результатом: нас, очевидно, интересует ситуация, когда сервис либо станет отвечать на запросы с неприемлемой задержкой, либо будет возвращать неверные данные, либо вовсе перестанет подавать признаки жизни для всех запросов или лишь для их части.
Давайте представим, что мы с вами написали некоторый сервис — для определённости скажем, что веб-сервис, но это не столь важно. Чтобы убедиться, на что мы с ним можем рассчитывать, мы начинаем «обстреливать» его запросами, наблюдая за поведением как самого сервиса, так и за нагрузкой на серверах, где он крутится. Хорошо, если заранее понятно, какие запросы нам нужно отправлять сервису (в этом случае мы можем подготовить массив запросов заранее, а после отправить его в наше приложение одним махом). Если же второй запрос зависит от результатов первого (простой пример — сначала происходит авторизация пользователя, и в следующие обращения к сервису включается информация об ID сессии), то генератор нагрузки должен быть способен генерировать тестовые запросы крайне быстро, в реальном времени.
С учётом обстоятельств и нашего знания об объекте тестирования выбираем инструмент(ы):
JMeter
Да, старый добрый JMeter. Он вот уже без малого двадцать лет (!) является частым выбором для многих вариантов и типов нагрузочного тестирования: удобный GUI, независимость от платформы (спасибо Java!), поддержка многопоточности, расширяемость, отличные возможности по созданию отчётов, поддержка многих протоколов для запросов. Благодаря модульной архитектуре JMeter можно расширить в нужную пользователю сторону, реализуя даже весьма экзотические сценарии тестирования — причем, если ни один из написанных сообществом за прошедшее время плагинов нас не устроит, можно взять API и написать собственный. При необходимости с JMeter можно выстроить, хоть и ограниченное, но распределённое тестирование, когда нагрузка будет создаваться сразу несколькими машинами.
Одной из удобных функций JMeter является работа в режиме прокси: указываем в настройках браузера в качестве прокси «127.0.0.1:8080» и посещаем браузером нужные нам страницы нужного сайта, тем временем JMeter сохраняет все наши действия и все сопутствующие запросы в виде скрипта, который позже можно будет отредактировать, как нужно — это делает процесс создания HTTP-тестов заметно проще.
Кстати, последняя версия (3.2), вышедшая в апреле этого года, научилась отдавать результаты тестирования в InfluxDB при помощи асинхронных HTTP-запросов. Правда, начиная как раз с версии 3.2, JMeter стал требовать только Java 8, но это, наверное, не самая высокая цена за прогресс.
Хранение тестовых сценариев у JMeter реализовано в XML-файлах, что, как оказалось, создаёт массу проблем: их совсем неудобно писать руками (читай — для создания текста необходим GUI), как неудобна и работа с такими файлами в системах управления версиями (особенно в момент, когда нужно сделать diff). Конкурирующие на поле нагрузочного тестирования продукты, такие, как Яндекс.Танк или Taurus, научились самостоятельно и на лету формировать файлы с тестами и передавать их в JMeter на исполнение, таким образом пользуясь мощью и опытом JMeter, но давая возможность пользователям создавать тесты в виде более читаемых и легче хранимых в CVS тестовых скриптов.
LoadRunner
Ещё один давно существующий на рынке и в определенных кругах очень известный продукт, большему распространению которого помешала принятая компанией-производителем политика лицензирования (кстати, сегодня, после слияния подразделения ПО компании Hewlett Packard Enterprise с Micro Focus International, привычное название HPE LoadRunner сменилось на Micro Focus LoadRunner). Интерес представляет логика создания теста, где несколько (наверное, правильно сказать — «много») виртуальных пользователей параллельно что-то делают с тестируемым приложением. Это даёт возможность не только оценить способность приложения обработать поток одновременных запросов, но и понять, как влияет работа одних пользователей, активно что-то делающих с сервисом, на работу других. При этом речь идёт о широком выборе протоколов взаимодействия с тестируемым приложением.
HP в своё время создала очень хороший набор инструментов автоматизации функционального и нагрузочного тестирования, которые, при необходимости, интегрируются в процесс разработки ПО, и LoadRunner умеет интегрироваться с ними (в частности, с HP Quality Center, HP QuickTest Professional).
Некоторое время назад производитель решил повернуться лицом к тем, кто не готов сразу платить за лицензию, и поставляет LoadRunner с бесплатной лицензией (где вписан лимит на 50 виртуальных пользователей, и запрещена небольшая часть всего набора поддерживаемых протоколов), а деньги берутся за дальнейшее расширение возможностей. Сложно сказать, насколько это будет способствовать повышению интереса к этому, без сомнения, занимательному инструменту, при наличии у него столь сильных конкурентов.
Gatling
Весьма мощный и серьёзный инструмент (не зря названный в честь скорострельного пулемета) — в первую очередь, по причине производительности и широты поддержки протоколов «из коробки». Например, там, где нагрузочное тестирование с JMeter будет медленным и мучительным (увы, плагин поддержки работы с веб-сокетами не особо быстр, что идейно конфликтует со скоростью работы самих веб-сокетов), Galting почти наверняка создаст нужную нагрузку без особых сложностей.
Следует учесть, что, в отличие от JMeter, Gatling не использует GUI и вообще считается средством, ориентированным на опытную, «грамотную» аудиторию, способную создать тестовый скрипт в виде текстового файла.
Есть у Gatling и минусы, за которые его критикуют. Во-первых, документация могла бы быть и получше, во-вторых, для работы с ним неплохо знать Scala: и сам Gatling, как инструмент тестирования, и тестовые сценарии пишутся именно на этом языке. В-третьих, разработчики «иногда» в прошлом кардинально меняли API, в результате можно было обнаружить, что тесты, написанные полугодом ранее, «не идут» на новой версии, либо требуют доработки/миграции. У Gatling также отсутствует возможность делать распределённое тестирование, что ограничивает возможные области применения.
Яндекс.Танк
Если коротко, Yandex Tank — это враппер над несколькими утилитами нагрузочного тестирования (включая JMeter), предоставляющий унифицированный интерфейс для их конфигурации, запуска и построения отчётов вне зависимости от того, какая утилита используется «под капотом».
Он умеет следить за основными метриками тестируемого приложения (процессор, память, своп и пр.), за ресурсами системы (свободная память/место на диске), может остановить тест на основе разных понятных критериев («если время отклика превышает заданное значение», «если количество ошибок за единицу времени выше, чем х» и т.д). Кстати, умеет отображать в реальном времени основные статистические данные теста, что бывает очень полезно прямо в процессе теста.
Танк используется и в самом Яндексе, и в других компаниях уже около 10 лет. Им обстреливают совершенно разные сервисы, с разными требованиями к сложности тестовых сценариев и к уровню нагрузки. Почти всегда для тестирования даже высоконагруженных сервисов хватает всего одного генератора нагрузки. Танк поддерживает разные генераторы нагрузки, как написанные специально для него (Phantom, BFG, Pandora), так и широко сторонние (JMeter). Модульная архитектура позволяет написать свой плагин под нужный генератор нагрузки и вообще прикрутить практически что угодно.
Для чего использовать разные генераторы нагрузки? Phantom — это быстрая «пушка» на C++. Один такой генератор может выдать до сотни тысяч запросов в секунду. Но для достижения такой скорости приходится генерировать запросы заранее и нельзя (не получается) использовать получаемые от тестируемого сервиса данные для генерации очередного запроса. В случаях, когда нужно исполнять сложный сценарий или сервис использует нестандартный протокол, следует использовать JMeter, BFG, Pandora.
В BFG, в отличие от Jmeter, нет GUI, тестовые сценарии пишутся на Python. Это позволяет использовать любые библиотеки (а их огромное количество). Часто бывает, что для сервиса написаны биндинги для Python, тогда их удобно использовать при написании нагрузочных сценариев. Pandora — это экспериментальная пушка на GoLang, достаточно быстрая и расширяемая, подходит для тестов по протоколу HTTP/2 и будет использоваться там, где нужны быстрые сценарии.
Внутри Яндекса для хранения и отображения результатов нагрузочных тестов используется специальный сервис. Сейчас наружу открыт его упрощенный аналог под названием Overload — он полностью бесплатен, его используют, в том числе, для тестирования открытых библиотек (например) и проведения соревнований.
Taurus
Taurus — ещё один фреймворк над несколькими утилитами нагрузочного тестирования. Возможно, вам понравится этот продукт, использующий похожий на Яндекс.Танк подход, но имеющий несколько другой набор «фич», и, пожалуй, более адекватный формат конфигурационных файлов.
Вообще, Taurus хорошо подойдёт в ситуации, когда мощность, скажем, Gatling важна для создания теста, но разбираться с Gatling (а также с написанием скриптов тестирования на Scala) нет желания или возможности: достаточно описать тест в куда более простом формате файла Taurus, настроить его на использование Gatling как инструмента создания нагрузки, и все Scala-файлы будут сгенерированы автоматически. Так сказать, «автоматизация автоматизации» в действии!
Taurus можно настроить на отправку статистики теста на онлайн-сервис BlazeMeter.com, который отобразит данные в виде нарядных графиков и таблиц. Подход не очень обычный, но заслуживающий внимания: движок вывода отчётов, очевидно, совершенствуется со временем, и постепенно будет выводить информацию ещё более симпатично.
Тестирование производительности
Тестировать производительность сервиса или приложения можно и нужно не только после завершения процесса разработки, но и во время неё, буквально так же, как мы делаем регулярные юнит- или регрессионные тесты. Правильно организованные, регулярные тесты производительности позволяют ответить на очень «тонкий» вопрос: не привели ли последние изменения в коде приложения к ухудшению производительности получившегося ПО?
Казалось бы, померить производительность — это так просто! Два раза взять timestamp (желательно с высокой точностью), посчитать разность, сложили-поделили, и всё — можно оптимизировать. Как бы не так! Хотя на словах этот вопрос звучит просто, на деле такого рода замеры довольно затруднительно производить, а сравнивать результаты разных замеров вообще не всегда разумно. Одна из причин: для сопоставления результатов тесты должны проходить над одними и теми же исходными данными, что, среди прочего, подразумевает воссоздание тестовой среды при каждом прогоне проверки, другая причина — сравнение субъективного восприятия времени работы тестового сценария может оказаться неточным.
Ещё одной причиной является сложность выделения влияния на производительность целого приложения работы отдельного его модуля, того, который мы сейчас правим. Усугубляя ситуацию, уточняем: ещё сложнее это влияние вычленить, если над кодом работает коллектив из более чем одного разработчика.
Один из подходов в такой ситуации состоит в тщательном создании полноценного тестового сценария, повторяющего работу с сервисом настоящего клиента, и прогоне его много раз, с параллельным анализом нагрузки на сервер, где проходит тестирование (таким образом, будет понятно, какая часть сценария создаёт нагрузку на отдельные ресурсы тестового сервера, что может дать дополнительную информацию по поиску мест, где следует подойти к производительности более серьёзно) — увы, не всегда можно такое позволить себе в реальной ситуации, просто потому, что объёмный тест, да ещё повторённый 10-20 раз, скорее всего будет слишком долгим, чтобы проводить его достаточно часто, а это полностью убьёт идею.
Второй подход, более подходящий к процессу разработки, заключается в организации ограниченного по масштабу, «микро-» или даже «нано-» тестирования отдельных мест кода (скажем, запуске одного метода или одной функции, но большое число раз — т.е., скорее, бенчмаркингу). Планирование такого тестирования требует дополнительных усилий со стороны разработчика, но результат окупается и общим улучшением производительности кода, и пониманием, как ведут себя отдельные части проекта по мере работы как над ними, так и над другими частями. Вот, для примера, пара инструментов для перформанс-тестирования:
JMH (Java Microbenchmark Harness) — это оснастка Java для сборки, запуска и анализа нано/микро/милли/макро-бенчмарков, написанных на Java и других языках с целевой платформой JVM. Сравнительно молодой фреймворк, в котором разработчики постарались учесть все нюансы JVM. Один из удобнейших инструментов, из тех, которые приятно иметь под рукой. JMH поддерживает следующие типы замеров: Throughput (замер чистой производительности), AverageTime (замер среднего времени выполнения), SampleTime (перцентиль времени исполнения), SingleShotTime (время вызова одного метода — актуально для замера «холодного» запуска тестируемого кода).
Поскольку речь идёт о Java, фреймворк учитывает в т.ч. и работу механизма кэширования JVM, и перед запуском бенчмарка несколько раз выполняет тестируемый код для «прогрева» кэша байт-кода Java-машины.
BenchmarkDotNet
На сегодняшний день BenchmarkDotNet — библиотека, в первую очередь, для бенчмарков, а не для перфоманс-тестов. Ведётся серьёзная работа над тем, чтобы библиотеку можно было также использовать на CI-сервере для автоматического детектирования перфомансных регрессий, но пока эти разработки не завершены.
Google Lighthouse
Замеры производительности фронтенда всегда стояли несколько особняком: с одной стороны, часто задержки связаны со скоростью реакции бэкенда, с другой — именно по поведению фронтенда (точнее, по скорости его реакции) пользователи часто судят о всём приложении, особенно, если речь идёт про веб.
В веб-фронтенде в отношении замеров производительности сейчас всё идёт в сторону использования Performance API и измерении именно тех параметров, которые имеют значение для конкретного проекта. Хорошим подспорьем окажется веб-сервис webpagetest.org с Performance API метками и замерами — он позволит увидеть картину не со своего компьютера, а с одной из многих точек тестирования, существующих в мире, и оценить влияние времени приёма-передачи данных через каналы интернет на работу фронтенда.
Этот продукт больше подходил бы для проверки страниц сайта на соответствие рекомендациям Google (и вообще best practices) как для веб-сайтов, так и для Progressive Web Apps, если бы не одна из его функций: среди проверок есть и тест на поведение сайта при плохом качестве веб-соединения, а также при полном отсутствии связи. Это не очень соотносится с перформанс-тестированием как таковым, однако, если задуматься, в некоторых случаях веб-приложение воспринимается «медленным» не потому, что медленно готовит данные, а потому, что условия его работы на машине пользователя, в его браузере, с учётом его соединения с интернетом — увы, не идеальны. Google Lighthouse как раз и позволяет оценить это влияние.
Да, тема бенчмарков и тестирования просто бесконечна. Про каждую из них можно и нужно писать пост, и не один. Однако, как мы с вами знаем, самым интересным будет не просто прочесть, а пообщаться, послушать, поспрашивать знающего человека, который, в силу своего опыта, заранее предупредит о многих мелких и крупных затруднениях, лежащих на пути освоения той или иной технологии.
Поэтому с радостью приглашаем вас посетить конференцию Гейзенбаг 2017 Moscow, которая состоится 8-9 декабря 2017 года, где будут, в частности, представлены доклады: