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" ?>

Материал подготовлен в рамках курса «Нагрузочное тестирование». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.

Комментарии (3)


  1. YuryB
    14.11.2021 00:11

    а он ещё живой? технология времён java 5


    1. AlexanderAlexandrovich
      20.11.2021 18:24

      А что сейчас нужно использовать?


      1. YuryB
        22.11.2021 10:34

        например groovy