Огляд 6 найпопулярніших технологій з категорії performance testing
Всім привіт. Я Сергій Моренець, розробник, викладач, спікер і технічний письменник, хочу поділитися з вами своїм досвідом роботи з такою цікавою темою, як тестування ефективності або продуктивності застосункiв.
Я написав кілька статей про таку бібліотеку як JMH, яка дозволяє перевірити ефективність якогось шматка коду (метода). Але що робити, якщо потрібно протестувати весь застосунок? JMH оптимізована на виконання в рамках JVM і нам доведеться звернутися до категорії технологій, відомих як performance testing tools.
Раніше я б назвав їх утилітами, але зараз це потужні системи з підтримкою розподіленої роботи та використання у хмарі. Інформації про них чимало, але вона має властивість застарівати. Тому я хотів би зробити огляд, актуальний на поточний, 2023 рік. Ну, і за останні роки у нас накопичилося достатньо досвіду роботи з цими системами, ми розглядаємо ці технології на деяких наших тренінгах.
Сподіваюся, цей огляд буде корисним для всіх, що планує займатися тестуванням ефективності.
Performance testing
Що таке Performance Testing? Це вид нефункціонального тестування, який дозволяє оцінити роботу вашого застосунку під певним навантаженням. Це і кількість одночасних користувачів, і обсяг введених даних, і апаратна конфігурація вашого сервера. Це найважливіший вид тестування, який дозволяє зрозуміти реакцію застосунку (кількість помилок чи час відповіді) на зовнішнє навантаження. При цьому performance testing неоднорідний і ділиться на 6 типів:
- Load testing — дозволяє визначити, при якому навантаженні (кількості користувачів) ваш застосунок відповідає вимогам, що відносяться до Quality of Service.
- Stress testing — тестування під позамежним навантаженням з метою визначення слабких місць у системі, які будуть не готові до таких випробувань.
- Spike testing (іноді вважається різновидом попереднього) — тестування застосунку, коли раптово збільшується кількість одночасних користувачів або обсягів даних.
- Endurance (або soak) testing — тестування під певним навантаженням досить довгий проміжок часу, щоб перевірити ваш застосунок на довгострокову стійкість.
- Volume (або flood) testing — тестування роботи застосунку при обробці дуже великих обсягів даних, наприклад, якщо ви працюєте з Big Data.
- Scalability testing — тестування роботи програми при зміні кількості одночасних користувачів (яка збільшується або зменшується).
Як оцінюється робота застосунку в таких умовах? Насамперед є готовий набір характеристик (метрик), які можна виміряти:
- час відгуку;
- пропускна спроможність (кб/сек);
- кількість оброблених запитів або транзакцій за секунду;
- завантаження мережі;
- використання CPU та пам’яті;
- відсоток помилок під час обробки запитів.
Середній час відгуку (latency) — дуже важливий параметр, і він може відрізнятися на клієнтській або серверній стороні. Тому що якщо вимірювати його на клієнті, то воно ще буде включати час підключення та очікування від сервера, поки той не зможе прийняти цей запит.
Є й інші характеристики, наприклад, 90% Line. Це середній час обробки тих запитів, які не потрапили в 90% найшвидше оброблених. Навіть серед запитів бувають щасливчики і бувають невдахи. Цей показник дозволяє визначити, скільки ж у середньому будуть оброблятися найповільніші запити.
Наступне питання — як тестувати наші застосунки. Якщо у вас є REST API, можна написати тести, використовуючи REST клієнт. Якщо у вас є Kafka брокери, можна надсилати повідомлення через Kafka SDK. Але це просте рішення «в лоб», яке доведеться потім підтримувати. У 2023 році є безліч інструментів для performance, і ви абсолютно точно зможете вибрати собі якусь технологію для ваших потреб.
Оскільки таких технологій дуже багато, все розглянути точно не вийде, візьмемо найпопулярніші.
JMeter
Це утиліта, написана на Java в 1998 року і, що дивно, все ще в строю і напевно є найвідомішою технологією в цьому списку. До її переваг можна віднести:
- Побудована на модульній архітектурі з підтримкою плагінів.
- Велика кількість «connectors» (HTTP, JDBC, JMS, LDAP, TCP).
- Підтримує розподілене тестування.
- Два режими використання (GUI та командний рядок).
- Підтримка параметризації у запитах.
- Можливість використання Groovy у тестових скриптах.
- Інтеграція з хмарними рішеннями (Blazemeter).

В принципі, єдиний суттєвий недолік JMeter — необхідність JVM (Java8+) для її запуску, що дещо ускладнює технологію в цілому. Та й сам JMeter займає приблизно 80 Мб.
Вочевидь, усе це впливає на споживання пам’яті. У Jmeter часто зустрічається OutOfMemoryError. Є навіть жарт, що, якщо ви не зустрічали таке виключення при роботі з JMeter, ви неправильно його використовували.
Але ці мінуси компенсуються можливостями JMeter. JMeter — одна з небагатьох утиліт у цьому огляді, що має повноцінний GUI. Тож сценарій її використання, наступний:
- Ви складаєте конфігурацію для тестів, робите перевірочний прогін, щоб перевірити, що все гаразд, і зберігаєте налаштування в
XML-файл внутрішнього формату. - Запускаєте тести з командного рядка.
- Переглядаєте результати в тому ж GUI.
Використання формату XML (а не JSON або YAML) є історичною спадщиною. У той же час для його зміни потрібно використовувати той самий GUI, змінювати такі файли вручну не рекомендується. А це призводить до того, що якщо ви зберігаєте ці файли в CVS-системі, досить складно зрозуміти суть змін з Git коммітів.
Загалом JMeter є найпопулярнішим і досить стабільним performance testing tools, про який є не тільки сотні статей та посібників, а й десятки книг, так що вивчити його точно не буде проблемою.
Gatling
Наступним за популярністю безумовно є Gatling. Він був написаний на Scala у 2012 році, це open source, але має комерційну версію Gatling Enterprise з підтримкою Cloud та розподіленого тестування.
Його мінус — відсутність GUI (все через командний рядок), зате є спеціальна утиліта Recorder. В принципі, якщо ви добре знаєте програмування, то можете використовувати Scala DSL або Java/Kotlin DSL для написання тестових сценаріїв. Але це дуже сильно піднімає вхідний поріг для використання Gatling, тому можна зробити простіше.
Ви запускаєте утиліту Recorder, далі робите потрібні дії з вашим застосунком у браузері, а Gatling перехоплює їх через проксі і створює готовий файл з тестовим сценарієм. Правда, потім, якщо ви хочете відредагувати цей файл, все одно потрібно знати програмування і Gatling DSL.

Загалом тестовий сценарій виглядає досить просто:
public class SampleSimulation extends Simulation {
HttpProtocolBuilder httpProtocol = http
.baseUrl("https://mysite.com");
ScenarioBuilder scn = scenario("SampleSimulation")
.exec(http("request_1")
.get("/"))
.pause(5);
{
setUp(
scn.injectOpen(atOnceUsers(1))
).protocols(httpProtocol);
}
}
А для його запуску можна використовувати і Maven/Gradle плагін:
mvn gatling:test
І наприкінці буде згенеровано барвистий HTML=звіт про роботу:

Locust
Проєкт Locust написаний у 2011 році на Python та позиціонує себе як «сучасний load testing tool». Він дозволяє здійснювати розподілене тестування, може запускатися як із CLI, так і з Web UI. Але він вимагає знання Python для написання тестових сценаріїв. Втім самі тести виглядають максимально компактно:
class SampleUser(HttpUser):
@task
def sample_task(self):
self.client.get("https://mysite.com")
Locust підтримує не лише стандартні способи комунікації (gRPC, REST, SOAP), але й багато інших (Kafka, MQTT, Selenium та WebSocket) за допомогою плагінів. Ось як виглядає сам звіт про роботу в режимі реального часу:
K6
K6 — порівняно новий проєкт, розроблений у 2017 році Load Impact testing service та потім придбаний у 2021 році компанією Grafana Labs. Він написаний на Go та підтримує скрипти на мові JavaScript.
K6 досить швидко розвивається. Вже зараз його можна використовувати у трьох варіантах — локальний запуск, розподілений (у Kubernetes кластері) та хмарний K6 Cloud.
Ще одна перевага K6 — модульність і можливість розширити існуючу функціональність сторонніми розробниками. За рахунок вбудованих модулів можна працювати з Redis і WebSockets. Є й експериментальні модулі, наприклад, модуль browser: він перевірить ефективність не вашого бекенда, а фронтенда, тобто те, як працює ваш застосунок у браузері. Вже зараз є більш як 50 розширень для різних сценаріїв використання, починаючи з інтеграції з Mongo і Neo4j.
K6 генерує звіти у форматах CSV та JSON. А відправляти їх може практично в будь-яку систему агрегації та візуалізації, починаючи з CloudWatch, і закінчуючи Kafka та ElasticSearch. Причому тестування може бути мануальним, а може бути автоматизованим. Для прихильників CI/CD можна інтегрувати K6 з GitHub, GitLab або Jenkins, щоб він запускав benchmarks під час кожної збірки.
Що, якщо ви не знаєте JavaScript і не хочете вивчати K6 API, але у вас є багато запитів, збережених у Postman? Не біда, K6 вміє імпортувати Postman колекції разом з усіма даними і конвертувати в JavaScript код.
Хочете перейти на K6, але у вас є багато старих сценаріїв від JMeter? Не біда, K6 вміє конвертувати їх у JavaScript код. Більше того, якщо все, що у вас є — це специфікація OpenAPI/Swagger, K6 і тут вам прийде на допомогу, сконвертувавши її у свої скрипти.
Але навіть якщо у вас немає нічого, то і тут ви можете обійтися без знання JavaScript і DSL. Досить використовувати так званий Test Builder — UI, який дозволить створити тестовий сценарій в інтерактивному режимі і зберегти його як JavaScript. Щоправда, для цього потрібно використовувати K6 Cloud (але це безкоштовно).
Загалом K6 справив на мене враження найтехнологічнішого проєкту і, що головне, — developer-friendly, який намагається забезпечити розробників тим, що їм потрібно. Якщо його порівнювати з JMeter, наприклад, це все одно як порівнювати Maven і Gradle. Кожен сам вирішує, що для нього є кращим — стабільність чи інноваційність, декларативний чи імперативний підхід при описі тестових сценаріїв.

Taurus
Taurus — open source фреймворк для Continuous Testing, розроблений компанією Blazemeter у 2015 році, який дозволяє інтегруватися з іншими технологіями тестування, такими як JMeter, Gatling або Selenium.
Чому розробники найменш охоче використовують performance test-ing tools? Кожна з них має свій CLI, API, DSL і UI (якщо є). Тому Taurus пропонує щось на зразок фасаду. Ви описуєте абстрактну тестову конфігурацію на YAML (або JSON), а потім до неї підключаєте той чи інший модуль (JMeter або Gatling).

Ну, і результати вимірювань можна відправити в Blazemeter для аналізу та перегляду. Таким чином, вам для використання того ж JMeter або Gatling потрібно лише вивчити Taurus DSL і роботу з командним рядком.
Wrk
Проєкт Wrk написав на С у 2012 році Вілл Глозер. І десь до 2015 року його активно підтримував, після чого, по суті, перестав розвивати. Можливо, це пов’язано з тим, що він реалізував усе, що хотів, а можливо, з тим, що він перейшов на Rust і Go.
Але ми живемо в епоху open-source. Тому інший ентузіаст Гіл Тене в 2015 році підхопив цей проєкт, зробив його fork і назвав Wrk 2. Гіл додав багато потрібних речей, перевів проєкт на HdrHystogram і в цілому продовжує розвивати його.
Wrk дуже простий у використанні (його, мабуть, перевершує в мінімалізмі тільки ApacheBench або ab). Це утиліта розміром 30(!) Кб, яка дозволяє надсилати запити на сервер HTTP. Тут навіть є можливість налаштування запитів за рахунок скриптів такою екзотичною мовою як Lua. Не думаю, що хтось захоче його вивчати заради load testing, але якийсь найпростіший скрипт можна написати.
Wrk 2 не підтримує останні тенденції HTTP, такі як TLS 1.3, HTTP/2 і тип паче HTTP/3. У чому тоді його перевага? Це мінімальне використання ресурсів під час роботи. Як би ви не навантажували його під час тестів, він не перейде межу в 5 Мб пам’яті, що використовується. Як стверджує його автор, він легко може обробляти мільйони запитів на секунду. При цьому навіть для 100 тисяч одночасних запитів достатньо
Технологія настільки проста, що на Stackoverflow всього 42 питання по ній (причому за двома версіями). Порівняйте це з 18 тисяч питань на JMeter. Тож його можна порекомендувати тим, хто не має часу на вивчення складніших технологій.
Наприкінці узагальнена порівняльна таблиця розглянутих технологій.
Технологія | Розмір (мб) | Період розробки | Спосіб використання | Написан на | Тестові сценарії |
JMeter | 80 | 1998 - | GUI/CLI | Java | XML |
Gatling | 80 | 2012 - | CLI або Maven/Gradle плагин | Scala | Scala/Java/Kotlin DSL |
Locust | 3 | 2011- | CLI/Web UI | Python | Python |
K6 | 49 | 2017 - | CLI | Go | JavaScript |
Wrk/Wrk 2 | 0.03 | 2012 - | CLI | C | Lua |
Висновки
У цій статті я розглянув 6 найпопулярніших технологій з категорії performance testing. Зрозуміло, вивчити все немає жодної фізичної можливості. Я впевнений, що цю статтю прочитають ті, хто використовують Artillery, Apache Drill, Siege чи Vegeta.
У будь-якому випадку, якщо ви шукаєте собі сучасний і надійний засіб тестування, то якийсь один з цих шести вам точно підійде. Всі вони мають абсолютно різні можливості, зручність і способи використання, рівень входження, необхідність знання програмування. Вам лише потрібно вибрати щось одне, виходячи з вашого досвіду та вимог проєкту.
А в другій частині цієї статті я проведу безпосереднє тестування, використовуючи дані performance testing tools, проаналізую їх реальні можливості та порівняю результати.
4 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів