Досвід автоматизації тестування серверного REST API за допомогою Jmeter

У даній статті мова піде про досвід автоматизації функціонального і навантажувального тестування API протоколу RTLSCP. Серверна частина системи локального позиціонування RealTrac складається з основного (core) сервера, який зв'язується з пристроями по протоколу INDD (InterNanoCom Protocol) і сервера додатків (appserver). Сервер додатків спілкується з зовнішніми клієнтами і основним сервером за допомогою протоколу RTLSCP (Real Track Location System Communication Protocol). Клієнти також можуть безпосередньо звертатися до основного сервера за RTLSCP.

RTLSCP реалізує архітектуру REST і дозволяє в запитах і відповідях передавати дані в форматі JSON, KML і PNG. Причому спілкування з нього може відбуватися як по HTTP/HTTPS, так і за WS/WSS (Websocket). Цей протокол забезпечує зовнішнього клієнта великим функціоналом:

  • отримання різної інформації про пристрої — локація, статуси, стан і т. д.;
  • передача керуючих команд на сервер — зміна параметрів пристроїв, налаштування сервера, відправлення повідомлень на пристрої, завантаження карти і т. д.;
  • отримання звітів за пристроїв, статусу роботи системи від Quality of Service.
  • безліч інших корисних функцій.
Важливо, що протокол, з боку сервера додатків обростає додатковими клієнт-специфік функціоналом від проекту до проекту. Як же це все тестувати? Вручну виходить довго і клопітно, тестувальник швидше зненавидить весь світ поки пройдеться по всім командам специфікації RTLSCP API більш ніж в 120 сторінок. Очевидно, цей процес необхідно автоматизувати.

Тестування системи проводиться під Linux. Спочатку ми намагалися написати автотесты “на коліні“. Перепробували кілька варіантів. Генерація запитів з випадковими даними та відправка їх на вхід утиліти для навантажувального тестування Siege. В цьому випадку ми отримуємо тільки навантажувальне тестування без можливості аналізу вмісту відповіді від сервера. Реалізація автотестів на Python і проста відправка запитів через urllib. Тут все веселіше з аналізом відповіді, але виходить громіздкий код, в який складно вникати сторонній людині і довго модифікувати.

Рішенням всіх наших проблем став несподівано знайдений Jmeter від Apache. Хоч на перший погляд його графічний інтерфейс викликає страх у обивателя, на ділі цей інструмент допоміг знайти велику кількість багів і заощадити багато часу на тестуванні RTLSCP API.

Рис. 1. Графічний інтерфейс Jmeter.

Буквально за місяць вдалося покрити автотестами майже всі доступні команди RTLSCP. У процесі створення скриптів, природно, були і виправлялися помилки і неточності як на стороні сервера, так і в самому протоколі. Так як ніяких особливих знань базова робота в Jmeter не вимагає, напрочуд швидко автоматизацію тестування вийшло ввести і нового співробітника.

Про інструменті вже існує певна кількість статей (варто звернути увагу на цю на хабре, тому розписувати всі його функції детально не будемо. Зупинимося лише на найцікавіших моментах, які запам'яталися за час використання Jmeter.

Автоматизація перевірки сервісу авторизації і розмежування прав доступу для різних користувачів пройшла на ура. Без будь-яких складнощів в кілька десятків кліків вийшло організувати створення акаунтів і призначення прав доступу до випадковим ресурсів.


Рис. 2. Так виглядає реалізація перевірки облікових записів.

За допомогою BeanShell PostProcessor (Post тут означає, що скрипт запускається після виконання запиту) обробляємо відповідь на запит всіх доступних в системі ресурсів. Отримуємо їх кількість і генеруємо випадкові Id ресурсів для подальшого присвоєння створеним акаунтів прав доступу до них. Це здійснюється наступним кодом на BeanShell:
import java.util.regex.*;
import java.util.*;
import java.util.Random;

String response = prev.getResponseDataAsString();
Pattern pattern = Pattern.compile("id");
Matcher matcher = pattern.matcher(response);
int count = 0;
while (matcher.find())
count++;
Random rd=new Random();
Set resSet = new HashSet();
while (resSet.size()<4) 
resSet.add(rd.nextInt(count));
int i=1;
Iterator iterator = resSet.iterator();
while (iterator.hasNext()) {
vars.put("resForCombo"+i,iterator.next().toString());
i++;
}


Потім з відповіді на запит інформації про ресурс за його Id отримуємо URL за допомогою Regular Expression Extractor:


Рис. 3. Використання Regular Expression Extractor.

Тут все очевидно, в змінну res1Addr поміщається вміст відповіді, вирізане по регулярному выражени. В кінці проводимо перевірку всіх створених облікових записів та їх права доступу до ресурсів. До речі, обробка Cookies для авторизації Jmeter реалізується простим додаванням елемента HTTP Cookie Manager.

Елементи типу check AUTH_ACCOUNT_ADDED_INTO_GROUP на малюнку 2 потрібні для перевірки того, що кожна дія користувача, вчинене над акаунтами записалося у відповідна подія в історії подій (Одержуваної також через RTLSCP).

Під час розробки автотестів був вкрай корисний вбудований генератор випадкових чисел. В будь-якому місці в Jmeter можна використовувати цю функцію. Розіграти число в заданому діапазоні:

${__Random(300,180000)}


Або згенерувати рядок певного розміру і випадкового змісту:

${__RandomString(${__Random(3,30)},ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,)}


Сподобалося, що в Jmeter будь-яку дію можна реалізувати як в коді BeanShell, так і з допомогою вбудованих інструментів. Наприклад, отримати кількість доступних в системі ресурсів (вище ми це робимо через BeanShell PostProcessor ) можна реалізувавши Regular Expression Extractor, в якому в полі No Match. слід просто вказати -1. В цьому випадку створюється змінна {Reference Name}_matchNr, що містить кількість знайдених у відповіді по регулярному виразу рядків. Так і відповідь на будь-який запит можна аналізувати в коді BeanShell і виставляти прапори статусу виконання елемента:

//Get response
response = prev.getResponseDataAsString();
//Check login
if (!response.contains("\"login\":\"${ulogin_g1}\"")) {
log.error("### login NOK!");
Failure= true;
//Check timestamp
} else if(!response.contains("\"create_ts\":${createTS_g1}")) {
log.error("### create_ts NOK!");
Failure= true;


Можливість коментування кожного елемента робить автотест читабельним і дозволяє посилатися на тікет в багтрекері, наприклад, Redmine:


Рис. 4. Коментування елементів.

Відключення ресурсномістких перевірок і додавання в Thread Group автотеста користувачів у полі Number of Treads (users) перетворює наш функціональний автотест у навантажувальний. Тепер проект запускається одночасно з вказаної кількості потоків і навантажує сервер.


Рис. 5 Навантажувальне тестування.

Результати виконання автотеста можна отримати в будь-якому зручному вигляді, як переглянути у графічній оболонці через View Results Tree, так і файлами логів з різними налаштуваннями:


Рис. 6 Отримання результатів.

Також варто відзначити можливість в режимі реального часу відправляти результати або будь-яку іншу інформацію про статус автотеста в різні сервіси (JDBC, JMS, Webservice). Наприклад, на Graphite з подальшим відображенням в Grafana:


Рис. 7 Відправка результатів.

Природно, у Jmeter існує деяка кількість негативних властивостей. Наприклад, не завжди зручний графічний інтерфейс і баги в ньому. Але в нашій ситуації, коли терміново (і найважливіше, безкоштовно) потрібно покрити автоматичними тестами велику кількість функцій спілкування клієнтів з сервером через протокол, Jmeter виявився незамінним інструментом тестувальника.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.