Jmeter处理API响应中复数数据:利用JDBC返回的ArrayList对象转成JSON格式断言文本

一、前言

1. API接口响应的JSON格式文本

一般而言,API接口的响应普遍是一个JSON格式文本。而一部分接口不止返回1条数据,而会返回复数数据。

举个例子,有这么个接口。根据status去查询用户email,返回结果不止一个用户。大致结构如下。

{
    "errCode": "0",
    "data": [{
        "Id": 1,
        "Email": "[email protected]"
    }, {
        "Id": 2,
        "Email": "[email protected]}"
    }, 
    ...
    ...
    ...
       {
        "Id": 9,
        "Email": "[email protected]}"
    }]
}

我们发现,最外层是{"errcode":0,"data":[...]},而data层的数据是可以通过数据库查询结果进行验证的。

2. JDBC返回的ArrayList对象

Jmeter中使用JDBC处理器去执行select语句后,在监听器里看到的查询结果是这样的表格形式。

id email
1 [email protected]
2 [email protected]

其实JDBC还会返回一个ArrayList对象。ArrayList内部是一个HashMap键值对,列名是key,数据是value。

根据上面示例中的查询结果,大概是这样的[{id=1, email="[email protected]"},{id=2,email="[email protected]"}]

//使用方法

ArrayList list = vars.getObject("sqlResult"); //JDBC处理器中申明的变量名

list.size() == 2

list.get(0) == {id=1, email="[email protected]"}

((HashMap)list.get(0)).get("email") == "[email protected]"

3. 转化思路

Data层JSON思路大致如下:

1. 写一个方法,传入name和value,返回"name": value(或者"name":"value")

2. 创建一个临时List,用来装属性。循环拼接成"name1":value1,"name2":"value2",..."name9":"value9"

3. 根据JDBC返回的List,循环拼接成复数数据{"id":1,"email":"[email protected]"},{"id":2,"email":"[email protected]"}

4. 演示接口示例

二、取数据库

1. 编写sql,取出Data部分中我们需的Id和Email值。要注意我们接口请求参数中有一个status,写在where条件里。

这里要注意 1. as 别名与接口响应中名称一致、2.注意排序

2. 添加一个JDBC后置处理器,将sql填入。并且在Result variable name文本框中填一个变量名,用来接收ArrayList对象

3. 这时Debug Sampler里可以看到这个ArrayList对象了。

三、转化结果

1. 添加一个BeanShell后置处理器,填入以下脚本内容

getParams() 用来手动转化成"name":int 或"name":"string"格式。用于嵌套json,譬如children:[另一个完整的json]。

getParamsByList() 用来自动转化,前提是你的sql返回的列名与属性名一致。

*这2个方法嫌放在beanshell里太丑,可以自己写个jar包来用。实际工作中不用变动方法内部!

import java.util.ArrayList;
import java.util.HashMap;

//手动传入value
static String getParams(String name, String value, boolean isString) {
	name = "\"" + name + "\"";
	if(isString) {
		value = "\"" + value + "\"";
	}
	return name + ":" + value;
}

//自动根据name去ArrayList取值
static String getParamsByList(ArrayList list, String name, int i, boolean isString){
	String value = "";
	if (((HashMap)list.get(i)).get(name.toLowerCase()) != null){
		value = ((HashMap)list.get(i)).get(name.toLowerCase()).toString();
	}else{
		value = "null";
		return getParams(name, value, false);
		}
		
	return getParams(name, value, isString);
	}

//第一步 指定JDBC返回值
ArrayList list = vars.getObject("User_sqlResult");

//第二步 传入参数名
String result = "";
for(int i = 0; i < list.size(); i++) {
	ArrayList tmpList = new ArrayList();

	tmpList.add(getParamsByList(list, "Id", i, false));
	tmpList.add(getParamsByList(list, "Email", i, true));
	
	String tmp = "";
	for (int l = 0; l < tmpList.size(); l++) {
		tmp += tmpList.get(l);
		if (l < tmpList.size()-1) { tmp += ","; }
	}
	result += "{" + tmp + "}";
	if (i < list.size()-1){ result += ","; }
}
//System.out.println(result);


//第三步 拼接首尾
result = bsh.args[0] + result + bsh.args[1] + "\n";
//System.out.println(result);

vars.put("Assertion", result);

2. 在下方填入JDBC里取出来的ArrayList变量名 和 add一下属性就能拼接成JSON格式,几十个参数都可以。

我们利用list特性把属性一个个add进去后,根据size()的长度 循环拼接单条数据

{"Id":-1,"Email":"[email protected]"}

再根据数据库取出来的list的长度,拼接完整数据列表

{"Id":-1,"Email":"[email protected]"},{"Id":202,"Email":null},{"Id":203,"Email":null},{"Id":204,"Email":null},{"Id":205,"Email":null},{"Id":588,"Email":null},{"Id":1443,"Email":"[email protected]"},{"Id":1444,"Email":"[email protected]"},{"Id":1445,"Email":"[email protected]"},{"Id":1446,"Email":"[email protected]"}

3. 目前还缺少{"errCode":"0","data":[ 和 ]} 把这个json框起来,在这一步中补全。

四、断言

1.我习惯把所有接口都取出Assertion,再放到BeanShell断言里检查。

(你也可以把取出来的Assertion放在普通的响应断言中去断言)

//断言
String Assertion = vars.get("Assertion"); 
String ResponseResult = prev.getResponseDataAsString();

//判断断言是否通过
if(ResponseResult.equals(Assertion)){ 
	Failure = false;  
}else{  
	Failure = true;
	FailureMessage = "接口响应:\r\n" + ResponseResult + "\r\n";  
	FailureMessage += "用例断言:\r\n" + Assertion;  
	
	String logInfo = "\n";  
	logInfo = logInfo + prev.getThreadName() + " " +  prev.getSampleLabel() + "\n";  
	logInfo = logInfo + prev.getSamplerData() + "\n";  
	logInfo = logInfo + prev.getResponseCode() + "\n\n";  
	logInfo = logInfo + prev.getResponseDataAsString() + "\n";  
	log.info(logInfo);  
}

2.如果API响应结果有问题,效果是这样的

猜你喜欢

转载自blog.csdn.net/tomoya_chen/article/details/82022611
今日推荐