背景:
在实现接口自动化时经常会遇到一种场景就是将数据库数据和页面展示的数据进行对比检查。
今天分享一下数据库中查询到的数据和get请求返回的网页数据对比方法。
数据库返回数据如下:
name Amount
美团 100000.48
大众点评 200000.80
抖音 300000.20
天猫 400000.52
京东 500000.52
淘宝 600000.52
在metershpere中数据获取方式选择结果存储方式:
如果使用这种方式,data返回的结构为Map List形式,如下:
[{Amount=100000.48, name=美团}, {Amount=200000.80, name=大众点评},{Amount=300000.20, name=抖音},{Amount=400000.52, name=天猫},{Amount=500000.52, name=京东},{Amount=600000.52, name=淘宝}]
而我们想要的数据是下面这样的,只需要名称和值映射,需要去除数据库字段名称
[{"美团":"100000.48"},{"大众点评","200000.80"}]
beanshell脚本如下:
import java.net.URI;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.*;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.entity.StringEntity;
import org.json.JSONObject;
import java.util.*;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
#获取数据库数据
List mySqlData = vars.getObject("data");
Map mySqlMap = new HashMap();
List myList = new ArrayList();
for(Map myItem :mySqlData)
{
mySqlMap.put(myItem.get("name"), myItem.get("Amount"));
myList.add(myItem.get("name"));
}
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
myFlag = true;
for(String myName :myList)
{
// 定义请求的参数
URI uri = new URIBuilder()
.setScheme("https")
.setHost("***.****.com")
.setPath("/**/**/interface/path")
.setParameter("pageIndex", "1")
.setParameter("pageSize", "1")
.build();
// 创建http请求
HttpGet request = new HttpGet(uri);
request.setHeader("Content-type", "application/json");
request.setHeader("Cookie", "${cookie}");
log.info(uri.toString());
//response 对象
CloseableHttpResponse response = null;
response = httpclient.execute(request);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
// log.info(content);
JSONObject jsonObject = new JSONObject(content);
int myCode = jsonObject.getInt("code");
if (myCode==200)
{
JSONObject dataObject = jsonObject.getJSONObject("data");
JSONObject listObject = dataObject.getJSONArray("list").getJSONObject(0);
String values = listObject.getString("values").replace(",","");
String mySqlSales = mySqlMap.get(myName).toString();
if(values.equals(mySqlSales))
{
log.info(myName+" 价格相等为:"+values);
}
else
{
myFlag=false;
AssertionResult.setFailureMessage(myName+" 价格不相等,页面价格为:"+values+" 数据库价格为:"+mySqlSales);
}
}
else
{
myFlag=false;
AssertionResult.setFailureMessage(myName+" 页面中无记录 "+content);
}
}
else
{
myFlag=false;
AssertionResult.setFailureMessage(content);
}
if(myFlag)
{
AssertionResult.setFailure(false);
}
else
{
AssertionResult.setFailure(true);
}
}
说明:
1. List mySqlData = vars.getObject("data"); 在这里vars.getObject 用来获取对象或列表,而beanshell中vars.get("someStr") 返回的则是字符串,如果要想获取到整型,需要转换一下
String mySomeStr=vars.get("someStr")
int myInt = Integer.parseInt()
2. 在发送get请求时参数要单独写,不可直接复制粘贴到 .setPath("/**/**/interface/path")方法中,因为"/**/**/interface/path" 后面如果带?会被转码,导致请求无法正确识别,而是需要使用.setParameter("pageIndex", "1")方式添加参数。
3. String content = EntityUtils.toString(response.getEntity(), "UTF-8"); 返回的是字符串需要使用JSONObject进行转化才能对其中字段进行提取
JSONObject jsonObject = new JSONObject(content);
JSONObject dataObject = jsonObject.getJSONObject("data");
JSONObject listObject = dataObject.getJSONArray("list")
4. 断言的设置需要使用这种方式:AssertionResult.setFailure(false);
5. 数据库获取还有一种列存储的方式,如:列1,列2,列3,列4,这种方式只要保证列名个数和数据库查询语句返回的一致,中间用逗号隔开即可,名称并不需要和sql语句返回的一致,甚至可以使用中文名。
int myLen = Integer.parseInt(vars.get("v4_#")); 这种方式就可以获取V4列的数据行数,如果具体取第几行的数据,之前写下标即可,下面从1开始,不是0,如获取V4列第一行数据:
vars.get("v4_1") 即可。在添加按列存储时,这些值就会被默认加到场景变量里面。