【Jmeter简介】
Apache JMeter是Apache组织开发的基于Java的压力测试工具,目前常见是用来做软件的接口测试和压力测试。
【问题背景】
使用jmeter进行测试时,一般使用正则表达式进行取值作为接口的传参。但如果当接口返回有多个list,需要对每个list中同一个字段进行取值,如果采取正则表达式进行提取数据,得需要靠人工先判断是否存在这个值,然后再去确定要提取的数据在多少位。比如接口返回的responseBody有AcctDtlsLst、PcrList、TdAcctNbrLst 3个list,我们要对某个list取AcNo这个字段名的值。如果需要取TdAcctNbrLst中第2个AcNo的值,使用正则表达式时需要先数下TdAcctNbrLst中第2个AcNo的值在整个responseBody排在第8位。
"responseBody":
: {
: : "AcctDtlsLst":
: : [
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6224271190410419-101",
: : : },
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6224271190412738-101",
: : : },
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6224271190415756-101",
: : : },
]
: : " PcrList ":
: : [
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6223210000823107",
: : : },
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"62242711904104190",
: : : },
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"62242711904104198",
: : : },
]
"TdAcctNbrLst":
: : [
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6224271190410419-106",
: : : },
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6224271190410419-107",
: : : },
: : : {
: : : : "AcName":"马云",
: : : : "AcNo":"6224271190410419-108",
: : : },
]
使用正则表达式如下:
正则表达式.png
因此针对数据比较大且返回有多个list,需人工去判断需要取的值是否存在并且在什么位置,效率会有所降低并且容易出错。因此针对这种情况可以使用jmeter自带的功能后置处理器BeanShell PostProcessor,分别提取每个list的值。
【BeanShellPostProcessor简介】
BeanShellPostProcessor 是一个轻量级的面向Java的脚本语言,借用了JMeter对于BeanShell支持的特性,允许使用标准的Java语法来处理Json数据。
【正则表达式与BeanShell的对比】
在jmeter中都可以使用正则表达式和BeanShellPostProcessor用来提取数据,下面是对他们的优缺点进行对比,如图:
正则表达式与BeanShell的对比.png
通过对比发现,BeanShellPostProcessor可以使用Java进行逻辑判断提取更多复杂的值。因此可以提取接口返回多个list且每个list有多个同一字段的值。下面将对BeanShell PostProcessor的具体使用方法做详细的说明。
【BeanShell PostProcessor使用方法】
1、 下载fastjson-1.1.6.jar
下载fastjosn.jar包用以解析json数据,下载链接如下,然后把jar包放在jmeter文件的lib下就可以了。
https://pan.baidu.com/s/1hrT0Unq
2、 添加后置处理器—BeanShell PostProcessor
在需要获取接口返回的值的接口处添加-后置处理器-BeanShellPostProcessor。
添加后置处理器.png
3、在BeanShell PostProcessor里输入下面的代码,用以解析responseBody的数据并取出list中某个AcNo的值。
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
String json=prev.getResponseDataAsString();
JSONObject jso = JSON.parseObject(json);
JSONObject responseBody = jso.getJSONObject("responseBody");
JSONArray List = responseBody.getJSONArray("PcrList");
vars.put("AcctNo",List.getJSONObject(0).getString("AcNo"));
JSONArray List2 = responseBody.getJSONArray("AcctDtlsLst");
vars.put("AcctNo2",List2.getJSONObject(0).getString("AcNo"));
JSONArray List3 = responseBody.getJSONArray("TdAcctNbrLst");
vars.put("AcctNo3",List2.getJSONObject(2).getString("AcNo"));
图片 3.png
4、 在接口需要传参的字段引入AcctNo/AcctNo2/AcctNo3
图片 4.png
总结
对于数据量小建议大家还是使用正则表达式,方便快捷。但如果数据量大,或者对取值有特殊要求可以考虑使用BeanShell PostProcessor。当然还有更复杂的情况,比如返回的list中又包含list,或者需要取某种状态下的数据,后续再继续研究。