Jmeter中beanshell常用语法总结
BeanShell前置处理器、BeanShell取样器、BeanShell后置处理器,它们之间的区别:
1、BeanShell前置处理器、BeanShell后置处理器 比 BeanShell取样器多一个重置解释器(Reset Interpreter),意思是指:对于每一次处理是不是都要进行重置;
2、在JMeter中BeanShell取样器是当成线程处理的,所以运行时是有一定的消耗的,而使用BeanShell前置处理器、BeanShell后置处理器总体来说比BeanShell取样器消耗低,相当于少起一个线程。
关注点1:
BeanShell PreProcessor前置处理器特有函数(在发送之前运行):
示例1:获取本次请求的入参body中的内容
导包:import org.apache.jmeter.config.Arguments; //Jmeter4.0及以上自带,需导包一次
Arguments argss = sampler.getArguments();
String argss_str = argss.getArgument(0).getValue();
log.info(argss_str);
示例2:获取本次请求的API路径
String path = sampler.getPath();
log.info(path);
关注点2:
BeanShell PostProcessor后置处理器特有函数(在返回相应之后运行):
示例1:获取本次请求的相应内容
String response = prev.getResponseDataAsString();
log.info(response);
关注点3:
Json字符串类型转为Json对象类型:
示例1:阿里的fastjson-1.2.70 jar包
导包import com.alibaba.fastjson.*; //下载fastjson-1.2.70 jar包,放到lib目录后重启Jmeter可用
JSONObject JsonObj= JSON.parseObject(JsonStr);
示例2:org.json_1.0.0.v 版本jar包
导包 import org.json.*;
JSONObject JsonObj= new JSONObject(JsonStr);
获取Json对象中的对象、数组、字段
eg: JsonObj:{
keyinfo:{
"documentno": "PYJK20200106123456789"
},
dealinfo:[{
"businesscode": "N99"
},
{
"businesscode": "N98"
}]
}
以阿里巴巴包为例
JSONObject keyinfo = JsonObj.getJSONObject("keyinfo"); //获取json对象中的对象
String documentno = JsonObj.getJSONObject("keyinfo").getString("documentno"); //获取json对象中的字段值
JSONArray dealinfo = JsonObj.getJSONArray("dealinfo"); //获取json对象中的数组
JSONObject keyinfo = JsonObj.getJSONArray("dealinfo").getJSONObject(0); //获取json数组中的对象,索引表示第几个对象
String businesscode = JsonObj.getJSONArray("dealinfo").getJSONObject(0).getString("businesscode"); //获取数组中对象的字段值
示例3:
需求:后置处理器中提取sample返回json数据中所有name字段值,返回的json格式如下:
{“body”:{“apps”:[{“name1”:”111”},{“name2”:”222”}]}}
1 2 3 4 5 6 7 8 9 10 11 12 | import org.json.*; String response_data = prev.getResponseDataAsString(); JSONObject data_obj = new JSONObject(response_data); String apps_str = data_obj.get( "body" ).get( "apps" ).toString(); JSONObject apps_array = new JSONArray(apps_Str); String[] result = new String[apps_array.length()]; for (int i=0;i<apps_array.length();i++){ JSONObject app_obj = new JSONObject(apps_array.get(i).toString()); String name = app_obj.get( "name" ).toString(); result[i]=name; } vars.put( "result" ,Array.toString(result)); |
示例4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import txtWrite.*; String response_data = prev.getResponseDataAsString(); String assert_data= "科目${num}" ; TxtWrite writeData= new TxtWrite(); if (response_data.indexOf(assert_data)!=-1) //请求的response中有包含自定义字符,则断言结果为false { Failure= false ; String message= "${__time(yyyy-MM-dd HH:mm:ss,)} 新建科目【" +assert_data+ "】成功" ; FailureMessage=message; writeData.contentToTxt( "D:/xykyInterfaceAutoTest.log" ,message); } else { Failure= true ; String message= "${__time(yyyy-MM-dd HH:mm:ss,)} 新建科目【" +assert_data+ "】失败----------" ; String response= "本次请求response数据:" +prev.getResponseDataAsString()+ "----------" ; String need_assert= "需要断言的数据:" +assert_data; FailureMessage=message+response+need_assert; writeData.contentToTxt( "D:/xykyInterfaceAutoTest.log" ,message+response+need_assert); } |
示例5:
场景描述:
- A接口返回值中有一个参数是数组类型且该数组中有多个值。
- B接口参数入参也是一个数组类型且它的参数必须是A接口动态返回的数组类型中全部的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | //注意必须导入这两个包,否则脚本运行会保存找不到这两个包提供的方法 import org.json.*; import java.util.Collections; public static void getValue(){ // 接收接口返回的数据 String response_data = prev.getResponseDataAsString(); // 转换成JSONObject 对象类型,这样java才能操作对象里面数据 JSONObject data_obj= new JSONObject(response_data); //判断当前响应数据是否为空,如果为空直接返回null,不再走后面的for流程。 if (data_obj.get( "data" ).equals( null )){ log.info( "接口返回数据列表为空" ); } else { // 获取JSONObject里面数组类型数据 data是个数组类型,将数组赋值给JSONArray JSONArray data_array = data_obj.getJSONArray( "data" ); int len = data_array.length(); // 创建List集合封装数组数据 ArrayList ids = new ArrayList(); // 遍历数组数据,将数据封装到集合中 for (int i=0;i<len;i++){ JSONObject jsonTemp = (JSONObject)data_array.getJSONObject(i); ids.add(jsonTemp.get( "id" )); } /* 这里非常关键,这里**也是一个坑**。 jmeter设置变量有两个方法,它们的使用场景区别非常大,用错了就无法取到值。 vars.put("key","value"): 该方法的value值只能是字符串类型,传入其他的类型就会报错。 vars.putObject("key",list、Object):该方法的value值类型可以接收Object类型、List、数组类型。 */ vars.putObject( "menuId" ,ids); log.info( "测试========" + ids); } } getValue(); |
示例6:
拼接字符串
JSON提取为:
提取后拼接为:
示例7:
将提取出来的Base64加密验证码进行解密:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import sun.misc.BASE64Decoder; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; String res = "${data}" ; //String aa = prev.getResponseDataAsString(); // 获取上一个请求的结果 log.info( "原始加密串:" + res); // base64解密 BASE64Decoder decoder = new BASE64Decoder(); String tmp = new String(decoder.decodeBuffer(res), "utf-8" ); log.info( "解密后的串:" + tmp); // 返回解密后的字符串 |
关注点4:
设置变量,变量存储在Jmeter内存中,只能是字符串类型的值
示例1:设置局部变量,作用于单个线程组
vars.put("a","123"); //设置变量a为123;
vars.put("documentno", documentno); //将变量documentno 设置为局部变量
vars.put("keyinfo", keyinfo.toString()); //将对象keyinfo转为字符串设置为局部变量
示例2:获取局部变量 (在同一个线程组中可获取到)
String a = vars.get("a"); //a="123"
String documentno = vars.get("documentno"); //documentno="PYJK20200106123456789"
JSONObject keyinfo = JSON.parseObject(vars.get("keyinfo")); //将获取的keyinfo字符串转为对象
BeanShell脚本中不用定义,可以直接使用变量,常用的内置变量和方法如下:
vars:操作Jmeter变量
vars.get("goodsid"); //从Jmeter中获取${goodid}变量
vars.put("goddsid",20); //将20保存在${goodid}变量中
prev:获取前面sampler返回的信息
getResponseDataAsString(); //获取相应信息
getResponseCode(); //获取相应code码
示例1:
//打印接口响应数据 log.info("用户列表的响应数据为"+prev.getResponseDataAsString()); #打印响应状态码 log.info("结果响应状态码"+prev.getResponseCode()); #打印当前IP内容 String IP = vars.get("host"); log.info("当前ip为:"+IP);
示例2:
1 2 3 4 5 6 7 8 9 10 11 | //打印接口响应数据 log.info( "商品sku库存接口的响应数据为" +prev.getResponseDataAsString()); //获取商品的库存值 String stock = vars.get( "stock" ); //因为获取到的库存值时string类型,需要转换成int int istock = Integer.parseInt(stock); //判断库存值是否大于500,大于500则购买10件 if (istock >10){ var .put( "buynum" , "10" ); } else { vars.put( "buynum" , "5" );} |
示例3:设置全局变量(作用于测试计划下的所有线程组)
props.put(); //用法与局部变量函数vars.put() 一致
示例4: 获取全局变量(测试计划下的所有线程组均可获取到)
String a = props.get("a"); //用法与局部变量函数vars.get() 一致
示例4:
1 2 3 4 5 6 7 8 | String name1 = vars.get( "name" ); //获取自定义变量中name的value值 log.info(name1); int age = 11; //vars.put里面只能放置Object或者String类型 String group = "北京" ; vars.put( "age1" ,age.toString()); //vars.put放置的value值需要是string类型 vars.put( "group1" ,group); log.info(vars.get( "age1" )+ "===" +vars.get( "group1" )); |
关注点5:
组建变量大对象VO
示例1:新建对象
JSONObject keyinfo = new JSONObject();
示例2:向对象中增加key-value
keyinfo.put("documentno", "PYJK20200106123456789");
示例3:新建数组
JSONArray dealinfo = new JSONArray();
示例4:向数组中增加对象,字段 ( 有先后顺序,索引 0,1,2。。)
dealinfo.add(dealinfo);
dealinfo.add(dealinfo);
dealinfo.add("aa"); //增加字段
示例5:向对象中增加对象,数组
JSONObject VO = new JSONObject();
VO.put("keyinfo", keyinfo);
VO.put("dealinfo", dealinfo);
关注点6:比较两个对象是否相等
以阿里巴巴jar包为例
import com.alibaba.fastjson.*;
public isObjValEqual(a_obj, b_obj){
Object a_key = a_obj.keySet(); //获取a对象中的所有键key,组成数组集合
Object b_key = b_obj.keySet(); //获取b对象中的所有键key,组成数组集合
Object key_list = maxArray(a_key, b_key); //获取长度大的数组集合
for(Object key : key_list){ //遍历每一个键key
String a_value = a_obj.get(key); //获取key对应的值
String b_value = b_obj.get(key);
if(!a_value.equals(b_value)){
log.info("两个对象中的"+key+"对应的值不一致");
return false;
}
}
return true;
}
关注点7:hash256,md5算法函数
导包 import org.apache.commons.codec.digest.DigestUtils; //下载org.apache.commons.codec_1.3.0.v 版本包
String md5 = DigestUtils.md5Hex(str).toLowerCase(); //Upper大写,Lower小写
String hash256= DigestUtils.sha256Hex(str).toLowerCase();
关注点8:Bean Shell基本语法
BeanShell的for循环集合,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 | String a = "aaa" ; int b = 111; List list = new ArrayList(); list.add(a); list.add(b.toString()); for (int i=0;i<list.size();i++){ log.info(list.get(i)); } //增强for循环的写法 for (object:list){ log.info(object);} |
BeanShell的数组写法,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | String[] str1 = new String[]{ "aa" , "bb" , "cc" }; //new一个String[]一维数组 String[][] str2 = new String[][]{{ "AA" , "BB" },{ "CC" , "DD" },{ "EE" , "FF" }}; //new一个String[][]二维数组 //遍历str1这个一维数组 for (int i=0;i<str1.length;i++){ log.info(str1[i]); } //遍历第二个二维数组 for (String[] strings:str2){ for (int i=0;i<strings.length;i++){ log.info(strings[i]); } } |
BeanShell中定义一个函数,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //定义一个方法 public void addlist(List list){ list.add( "aaa" ); list.add( "bbb" ); list.add( "ccc" ); } List list = new ArrayList(); //调用方法 addlist(list); //遍历list集合 for (int i = 0; i < list.size(); i++){ log.info(list.get(i)); } |
关注点9:vars内置对象put和get Object对象
如果需要获取或者放置非String类型数据,需要用putObject()和getObject()
1 2 3 4 5 6 7 8 9 10 11 12 | //Beanshell vars.putObject() vars.getObject()的使用 List list = new ArrayList(); list.add( "aaa" ); list.add( "bbb" ); //putObject()可以在vars对象中放置Object类型对象 vars.putObject( "list" ,list); //=========================== //获取Object list对象 Object Value = vars.getObject( "list" ); //log.info只能输出String类型变量 log.info(Value.toString()); |
关注点10:BeanShell的常用内置对象-cxt
cxt内置对象getPreviousResult()方法 调用请求/响应数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //SampleResult需要import对象 import org.apache.jmeter.samplers.SampleResult; SampleResult result = ctx.getPreviousResult(); //getRequestHeaders()方法返回String字符串 String RequestHeaders = result.getRequestHeaders(); //getResponseHeaders() 返回响应headers String ResponseHeaders = result.getResponseHeaders() //getResponseCode() 返回响应状态码字符串 String responseCode = result.getResponseCode(); //getURL() 返回请求URL对象 URL url = result.getURL(); log.info(RequestHeaders); log.info(RequestHeaders); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界