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”}]}}
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:
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接口动态返回的数组类型中全部的数据
//注意必须导入这两个包,否则脚本运行会保存找不到这两个包提供的方法
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加密验证码进行解密:
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:
//打印接口响应数据
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:
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循环集合,示例代码如下:
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的数组写法,示例代码如下:
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中定义一个函数,示例代码如下:
//定义一个方法
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()
//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()方法 调用请求/响应数据
//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);
浙公网安备 33010602011771号