BeanShell — один из самых продвинутых встроенных компонентов JMeter. Он поддерживает синтаксис Java и расширяет его такими функциями, как свободные типы, команды и закрытие методов. Если ваш тестовый пример нестандартен и его реализация с помощью встроенных компонентов JMeter становится сложной или даже невозможной, BeanShell может стать отличным вариантом для достижения ваших целей.
Сущности BeanShell в JMeter имеют доступ как к внутренним API JMeter, так и к любым внешним классам, которые загружены в classpath JMeter (обязательно поместите необходимые jar-файлы в папку /lib/ext
вашей установки JMeter и расположите все необходимые операторы "import" в начале ваших скриптов BeanShell).
Все версии JMeter предоставляют следующие компоненты с поддержкой BeanShell:
Beanshell Sampler — автономный сэмплер
Beanshell PreProcessor — препроцессор для другого сэмплера, который выполняется перед ним и может использоваться для предварительной настройки (т.е. для генерации некоторых входных данных).
Beanshell PostProcessor — постпроцессор, который выполняется после сэмплера и может быть использован для восстановления или очистки.
Beanshell Assertion — расширенное утверждение с полным доступом к API JMeter. Чтобы задать результат утверждения, можно использовать условную логику Java.
__Beanshell Function — функция JMeter, которая позволяет выполнять пользовательский код BeanShell во время запуска сэмплера.
ОСНОВНЫЕ ПРИМЕРЫ
Изменение переменных JMeter на лету
Предположим, что у вас есть пользовательская переменная "continue
" со значением "true
" где-то в цикле While
. Можете установить ее в значение "false
" с помощью этой простой команды:
vars.put("counter", "false");
Преобразование переменной JMeter в свойство
Для использования переменной "some_variable
" необходимо преобразовать свойство JMeter с тем же именем (например, в другой группе потоков).
props.put("some_variable",vars.get("some_variable"));
РАСШИРЕННЫЕ ПРИМЕРЫ
Передача файлов cookie между группами потоков
Если менеджер HTTP Cookie включен, следующий код может преобразовать куки JMeter в свойства.
import org.apache.jmeter.protocol.http.control.CookieManager;
CookieManager manager =
ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager").getObjectValue();
props.put("cookiecount",String.valueOf(manager.getCookieCount()));
for (int i=0;i<manager.getCookieCount();i++){
// code to convert Cookie information to JMeter Properties
props.put("cookie_name_" + i, manager.get(i).getName());
…..
}
После того как вся информация о cookie будет сохранена как свойство JMeter, можете восстановить cookie в другой группе потоков.
import org.apache.jmeter.protocol.http.control.CookieManager;
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.testelement.property.JMeterProperty;
CookieManager manager =
ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager").getObjectValue();
int count = Integer.parseInt(props.getProperty("cookiecount"));
for (int i=0;i<count;i++) {
Cookie cookie = new
Cookie(props.getProperty("cookie_name"+i),props.getProperty("cookie_value"+i), props.getProperty("cookie_domain"+i),props.getProperty("cookie_path"+i), Boolean.parseBoolean(props.getProperty("cookie_secure"+i)), Long.parseLong(props.getProperty("cookie_expires"+i)));
manager.add(cookie);
}
JMeterProperty cookieprop =
ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager");
cookieprop.setObjectValue(manager);
ctx.getCurrentSampler().setProperty(myprop);
Остановка теста в случае неудачи
Представьте, что у вас есть 48-часовой тест SOAK, запланированный на выходные, который явно зависит от элемента конфигурации набора данных CSV, требующего наличия исходных файлов CSV. Вы протестировали его с одним пользователем и одним циклом на машине разработчика, и все прошло нормально. Однако, когда вы загружаете его в свою среду эксплуатации и запускаете в режиме headless (без локального интерфейса), JMeter не может найти CSV-файл, и все 48 часов оказываются потраченными впустую. Чтобы избежать этой ситуации, используйте следующую проверку в самом первом сэмплере BeanShell:
File mycsvfile = new File("my.csv");
if (!mycsvfile.exists()) {
SampleResult.setSuccessful(false);
SampleResult.setResponseMessage("Failed to find my.csv file");
SampleResult.setResponseData("Unable to locate my.csv file under path: " + mycsvfile.getPath(),"UTF-8");
IsSuccess=false;
SampleResult.setStopTestNow(true);
}
Все вышеперечисленное + BlazeMeter
Этот пример демонстрирует простой вариант использования BeanShell с BlazeMeter при следующей структуре TestPlan:
Группа потоков (1 пользователь, 1 секунда ramp-up, всегда)
Контроллер While с пустым состоянием (всегда)
Счетчик (начало - 1, инкремент - 1, имя ссылки - счетчик)
HTTP-запрос (имя сервера - example.com)
Постпроцессор BeanShell
Постпроцессор BeanShell проверяет, содержит ли ответ HTTP-сэмплера домен example. Если нет, тест завершится неудачно и будет немедленно остановлен. Если содержит, то тест завершится после третьей итерации. В обоих случаях что-либо добавляется в журнал jmeter.log.
String response = new String(data);
int counter = Integer.parseInt(vars.get("counter"));
log.info("Starting iteration: " + counter);
log.info("Checking for \"Example Domain\" presense in response");
boolean found =response.contains("Example Domain");
log.info("Found - " + found);
if (!found)
{
prev.setSuccessful(false);
String errormsg = "\"Example Domain\" string isn't present in response";
prev.setResponseMessage(errormsg);
log.error(errormsg);
prev.setStopTestNow(true);
}
if (counter == 3)
{
log.info("Reached third iteration, stopping test");
log.error("Test ID " + props.get("blazemeter.test_id") + " ended at " + new Date());
stopTest();
}
void stopTest()
{
prev.setStopTest(true);
}
ПРЕДОПРЕДЕЛЕННЫЕ ПЕРЕМЕННЫЕ BEANSHELL В JMETER
Следующий раздел содержит самые важные и наиболее часто используемые классы API JMeter, открытые для компонентов BeanShell. Если вы посмотрите на нижнюю часть сэмплера BeanShell, то увидите следующее:
"Для сценария определены следующие переменные:
SampleResult, ResponseCode, ResponseMessage, IsSuccess, Label, FileName, ctx, vars, props, log".
SampleResult
SampleResult маппируется на класс JMeter org.apache.jmeter.samplers.SampleResult. Все поля и методы, описанные в javadoc, могут быть доступны и вызваны. Вот пример использования:
String currentURL = SampleResult.getUrlAsString();
ResponseCode
ResponseCode — это java.lang.String
, обозначающий код ответа выборки. Вот пример использования:
if (condition) {
ResponseCode = "200";
}
else {
ResponseCode = "500";
}
ResponseMessage
ResponseMessage — это java.lang.String
, представляющий сообщение ответа. Пример использования тот же, что и для ResponseCode.
IsSuccess
IsSuccess — это java.lang.Boolean
, который отражает, успешно ли прошел сэмплер. Если он установлен в true, сэмплер считается "пройденным". В противном случае он будет помечен как "неудачный".
if (condition) {
IsSuccess = true;
}
else {
IsSuccess = false;
}
Label
Label — это java.lang.String
, которая представляет собой метку сэмплера. Она может быть получена или установлена как обычная строка и будет отображаться в результатах тестирования как метка сэмплера.
FileName
FileName — это java.lang.String
, которая содержит имя файла скрипта BeanShell (то, что вводится в строке "Script file" сэмплера).
ctx
ctx
— это самая мощная переменная, доступная в BeanShell. Она представляет класс org.apache.jmeter.threads.JMeterContext
, который фактически является самим JMeter. Он предоставляет доступ на чтение и запись к базовому движку JMeter, сэмплерам и их результатам, а также к переменным/свойствам.
vars
vars
(переменные JMeter) — наиболее часто используемый компонент. Он является экземпляром класса org.apache.jmeter.threads.JMeterVariables
и предоставляет доступ на чтение/запись к текущим переменным, способен перечислять/изменять существующие переменные, создавать новые и получать вложенные свойства. Все переменные JMeter являются строками Java. Если вам нужно поместить что-то другое в переменную JMeter, вам нужно будет сначала привести это к строке. Следующий фрагмент кода демонстрирует, как сохранить предыдущие данные ответа сэмплера в переменную JMeter.
byte [] samplerdata = ctx.getPreviousResult().getResponseData();
String samplerdatastring = new String(samplerdata);
vars.put("samplerdata",samplerdatastring);
props
В сущности, это то же самое, что и "vars
", но вместо этого раскрываются свойства JMeter. Для получения дополнительной информации смотрите JavaDoc по java.util.Properties
и документацию JMeter по свойствам JMeter. Основное различие между props
и vars
заключается в том, что props
имеет "глобальную" область видимости, в то время как область видимости "vars
" ограничена текущей группой потоков.
log
log представляет класс org.apache.log.Logger и может быть использован для добавления сообщения в файл jmeter.log. Более подробную информацию смотрите в JavaDoc по logger. Ниже приведен пример использования:
log.info("This is a message with INFO level");
log.error("This is a message with ERROR level");
ОТЛАДКА СКРИПТОВ BEANSHELL
Поскольку BeanShell выполняется внутри движка Rhino, нет другой возможности увидеть, что не так, кроме как просмотреть файл jmeter.log на предмет чего-то вроде:
“Ошибка при вызове метода bsh”
и использования System.out.println
("something") или log.info
("something") для определения места сбоя скрипта.
УЗНАТЬ БОЛЬШЕ
Если вы новичок в JMeter и хотите узнать больше, запишитесь на наш бесплатный онлайн-курс по JMeter.
Более опытным пользователям JMeter стоит просмотреть веб-трансляцию по запросу "Как создавать расширенные сценарии нагрузочного тестирования с помощью JMeter".
Обязательно прочитайте весь наш список ресурсов по JMeter!
Как облако нагрузочного тестирования BlazeMeter дополняет и усиливает JMeter
Хотя JMeter представляет собой мощный и эффективный способ проведения нагрузочного тестирования, дополнительно рекомендуем воспользоваться BlazeMeter, который позволяет смоделировать до миллионов пользователей на одной удобной для разработчиков платформе самообслуживания. С помощью BlazeMeter вы можете протестировать производительность любого мобильного приложения, веб-сайта или API менее чем за 10 минут. Вот почему мы считаем комбинацию BlazeMeter/JMeter привлекательной для разработчиков:
Простая масштабируемость — Легко создавать крупномасштабные тесты JMeter. С помощью BlazeMeter вы можете запустить большие нагрузки гораздо проще, чем в собственной лаборатории.
Быстрое развертывание — Рекордер BlazeMeter поможет вам сразу же начать работу с JMeter, при этом BlazeMeter также предоставляет полные учебные пособия и советы.
Интерактивные отчеты на веб-основе — Вы можете легко делиться результатами с распределенными командами и преодолеть ограничения автономного пользовательского интерфейса JMeter.
Встроенный интеллект — BlazeMeter обеспечивает географическое распределение нагрузки по требованию, включая встроенное тестирование с учетом CDN.
Чтобы опробовать BlazeMeter, запросите демонстрацию.
<?php include path_to_theme()."/templates/_test_wizard_url_widget.tpl.php" ?>
Материал подготовлен в рамках курса «Нагрузочное тестирование». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.