文章目录
- 一、前言
- 二、实现代码
- 三、代码示例
- 四、最后
一、前言
对于上一篇文章(性能工具之 HAR 格式化转换JMeter JMX 脚本文件)还是有点问题。大家在使用的情况需要注意。
如果多个接口相同 path 路径且不同参数进行查询如:
上面接口如果不做处理生成脚本:
展开几个看看:
再点击下一个观察:
如果把上面脚本构建成一个接口,相同参数通过 CSV Data Set Config 或者其他参数文件方式处理就能实现这一想法,这里演示怎么通过BeanShell PreProcessor 来处理这样的想法。
二、实现代码
为了通过代码自动构建 BeanShell PreProcessor
脚本,将相同路径但不同参数的请求构建为一个参数数组,并通过随机数据给每次请求,我们可以按照以下步骤进行:
详细步骤:
- 创建 BeanShell PreProcessor:
- 创建一个 BeanShell PreProcessor 实例,并设置其脚本内容。
- 脚本内容将负责生成随机参数数组,并将这些参数传递给请求。
- 生成随机参数数组: 在脚本中生成随机参数数组,并将这些参数赋值给变量。
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)组装到测试计划中。
详细代码实现:
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);
执行后发现脚本没有写入任何数据,再次修改脚本为:
上面写入成功。
基于上面脚本可以修改成我们想要的脚本文件如:
// 构建 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代码:
成功转换成想要的参数文件。
三、代码示例
全部参考代码,如下:
// 初始化压测引擎
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 HashTreeHashTree testPlanTree = new HashTree();// 从以上初始化的元素构造测试计划testPlanTree.add(testPlan);HashTree threadGroupHashTree = testPlanTree.add(testPlan, threadGroup);// 第一个 HTTP Sampler - 打开 baidu.comHTTPSamplerProxy 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"));
四、最后
希望上面代码对大家有参考价值。
顺便问下,如果想解决下面接口我们应该怎么处理呢?
这里提供一个思路:
- 解析上面参数到一个对象中。
- 按 path 路径进行分组。
- 构建 jmx脚本,通过 path 路径获取分组后的参数文件构建 buildBeanShellScript 。
- 添加到 HashTree 中。