性能工具之JMeter 通过Java API生成 BeanShell PreProcessor 脚本

文章目录

一、前言

对于上一篇文章(性能工具之 HAR 格式化转换JMeter JMX 脚本文件)还是有点问题。大家在使用的情况需要注意。

如果多个接口相同 path 路径且不同参数进行查询如:

上面接口如果不做处理生成脚本:

展开几个看看:

再点击下一个观察:

如果把上面脚本构建成一个接口,相同参数通过 CSV Data Set Config 或者其他参数文件方式处理就能实现这一想法,这里演示怎么通过BeanShell PreProcessor 来处理这样的想法。

二、实现代码

为了通过代码自动构建 BeanShell PreProcessor 脚本,将相同路径但不同参数的请求构建为一个参数数组,并通过随机数据给每次请求,我们可以按照以下步骤进行:

详细步骤:

  1. 创建 BeanShell PreProcessor:
  2. 创建一个 BeanShell PreProcessor 实例,并设置其脚本内容。
  3. 脚本内容将负责生成随机参数数组,并将这些参数传递给请求。
  4. 生成随机参数数组: 在脚本中生成随机参数数组,并将这些参数赋值给变量。
java 复制代码
import java.util.Random;

Random rand = new Random();
String[] dictCodeStr = { "s_cache=17","s_cache","s" };
int randomIndex = rand.nextInt(dictCodeStr.length);
vars.put("paramPath", String.valueOf(dictCodeStr[randomIndex]));

将这些变量传递给请求。

  • 组装测试计划:
    将 BeanShell PreProcessor 和请求(例如 HTTPSampler)组装到测试计划中。

详细代码实现:

java 复制代码
BeanShellPreProcessor  beanShellPreProcessor = new BeanShellPreProcessor ();
beanShellPreProcessor.setName("BeanShell PreProcessor");
beanShellPreProcessor.setScript("sdsd");
beanShellPreProcessor.setComment("参数化文件");
beanShellPreProcessor.setProperty(BeanShellTestElement.TEST_CLASS, BeanShellPreProcessor.class.getName());
beanShellPreProcessor.setProperty(BeanShellTestElement.GUI_CLASS, TestBeanGUI.class.getName());
HashTree testPlanTreeShell = new HashTree();
testPlanTreeShell.add(beanShellPreProcessor);
threadGroupHashTree.add(baiducomSampler, testPlanTreeShell);

执行后发现脚本没有写入任何数据,再次修改脚本为:

上面写入成功。

基于上面脚本可以修改成我们想要的脚本文件如:

java 复制代码
// 构建 shell 脚本
    String beanShellScript = "import java.util.Random;\n" +
            "\n" +
            "   Random rand = new Random();\n" +
            "   String[] dictCodeStr = {paramList};\n" +
            "   int randomIndex = rand.nextInt(dictCodeStr.length);\n" +
            "   vars.put(\"paramPath\", String.valueOf(dictCodeStr[randomIndex]));";

    ArrayList<String> paraList = new ArrayList<>();
    paraList.add("s_cache=1726989090167&s_locale=zh-cn");
    paraList.add("s_cache=1726989090168&s_locale=zh-cn");
    beanShellScript = beanShellScript.replace("paramList", JSONObject.toJSONString(paraList).replace("[", "").replace("]", ""));

    BeanShellPreProcessor  beanShellPreProcessor = new BeanShellPreProcessor ();
    beanShellPreProcessor.setName("BeanShell PreProcessor");
    beanShellPreProcessor.setComment("参数化文件");
    beanShellPreProcessor.setResetInterpreter(false);
    beanShellPreProcessor.setProperty("parameters", "");
    beanShellPreProcessor.setProperty("filename", "");
    beanShellPreProcessor.setProperty("script", beanShellScript);
    beanShellPreProcessor.setProperty(BeanShellTestElement.TEST_CLASS, BeanShellPreProcessor.class.getName());
    beanShellPreProcessor.setProperty(BeanShellTestElement.GUI_CLASS, TestBeanGUI.class.getName());
    baiducomSampler.setPath("/" + "${paramList}");
    HashTree testPlanTreeShell = new HashTree();
    testPlanTreeShell.add(beanShellPreProcessor);

执行JAVA代码:

成功转换成想要的参数文件。

三、代码示例

全部参考代码,如下:

java 复制代码
// 初始化压测引擎 
StandardJMeterEngine jmeter = new StandardJMeterEngine();

 // JMeter初始化(属性、日志级别、区域设置等)
 JMeterUtils.setJMeterHome(jmeterHome.getPath());
 JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
 // 可以注释这一行,查看额外的日志,例如DEBUG级别
 JMeterUtils.initLogging();
 JMeterUtils.initLocale();

 // Test Plan 测试计划
 TestPlan testPlan = new TestPlan("创建JMeter脚本");
 testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
 testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
 testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());

 // Loop Controller 循环控制
 LoopController loopController = new LoopController();
 loopController.setLoops(1);
 loopController.setFirst(true);
 loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
 loopController.setProperty(TestElement.GUI_CLASS, LoopControlPanel.class.getName());
 loopController.initialize();

 // Thread Group 线程组
 ThreadGroup threadGroup = new ThreadGroup();
 threadGroup.setName("Example Thread Group");
 threadGroup.setNumThreads(1);
 threadGroup.setRampUp(1);
 threadGroup.setSamplerController(loopController);
 threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
 threadGroup.setProperty(TestElement.GUI_CLASS, ThreadGroupGui.class.getName());

 // JMeter测试计划,基本上是JOrphan HashTree
 HashTree testPlanTree = new HashTree();
 // 从以上初始化的元素构造测试计划
 testPlanTree.add(testPlan);
 HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);

 // 第一个 HTTP Sampler - 打开 baidu.com
 HTTPSamplerProxy baiducomSampler = new HTTPSamplerProxy();
 baiducomSampler.setDomain("baidu.com");
 baiducomSampler.setPort(80);
 baiducomSampler.setPath("/");
 baiducomSampler.setMethod("GET");
 baiducomSampler.setName("Open baidu.com");
 baiducomSampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
 baiducomSampler.setProperty(TestElement.GUI_CLASS, HttpTestSampleGui.class.getName());

 // 构建 shell 脚本
 String beanShellScript = "import java.util.Random;\n" +
         "\n" +
         "   Random rand = new Random();\n" +
         "   String[] dictCodeStr = {paramList};\n" +
         "   int randomIndex = rand.nextInt(dictCodeStr.length);\n" +
         "   vars.put(\"paramPath\", String.valueOf(dictCodeStr[randomIndex]));";

 ArrayList<String> paraList = new ArrayList<>();
 paraList.add("s_cache=1726989090167&s_locale=zh-cn");
 paraList.add("s_cache=1726989090168&s_locale=zh-cn");
 beanShellScript = beanShellScript.replace("paramList", JSONObject.toJSONString(paraList).replace("[", "").replace("]", ""));

 BeanShellPreProcessor  beanShellPreProcessor = new BeanShellPreProcessor ();
 beanShellPreProcessor.setName("BeanShell PreProcessor");
 beanShellPreProcessor.setComment("参数化文件");
 beanShellPreProcessor.setResetInterpreter(false);
 beanShellPreProcessor.setProperty("parameters", "");
 beanShellPreProcessor.setProperty("filename", "");
 beanShellPreProcessor.setProperty("script", beanShellScript);
 beanShellPreProcessor.setProperty(BeanShellTestElement.TEST_CLASS, BeanShellPreProcessor.class.getName());
 beanShellPreProcessor.setProperty(BeanShellTestElement.GUI_CLASS, TestBeanGUI.class.getName());
 baiducomSampler.setPath("/" + "${paramList}");
 HashTree testPlanTreeShell = new HashTree();
 testPlanTreeShell.add(beanShellPreProcessor);

 threadGroupHashTree.add(baiducomSampler, testPlanTreeShell);

 // 将生成的测试计划保存为JMeter的.jmx文件格式
 SaveService.saveTree(testPlanTree, new FileOutputStream("D:\\work\\jmx" + slash + "example1.jmx"));

四、最后

希望上面代码对大家有参考价值。

顺便问下,如果想解决下面接口我们应该怎么处理呢?

这里提供一个思路:

  1. 解析上面参数到一个对象中。
  2. 按 path 路径进行分组。
  3. 构建 jmx脚本,通过 path 路径获取分组后的参数文件构建 buildBeanShellScript 。
  4. 添加到 HashTree 中。
相关推荐
morris1317 分钟前
【SpringBoot】Xss的常见攻击方式与防御手段
java·spring boot·xss·csp
古人诚不我欺15 分钟前
jmeter常用配置元件介绍总结之函数助手
jmeter
川石课堂软件测试15 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
古人诚不我欺17 分钟前
jmeter常用配置元件介绍总结之取样器
jmeter
十叶知秋20 分钟前
【jmeter】jmeter的线程组功能的详细介绍
数据库·jmeter·性能测试
我非夏日21 分钟前
JMeter基础篇
jmeter
龙哥说跨境24 分钟前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
七星静香32 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员33 分钟前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU33 分钟前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea