
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" ?>
Материал подготовлен в рамках курса «Нагрузочное тестирование». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.
