- 前言:
从事接口自动化的小伙伴都比较清楚,需要解决上游接口的参数依赖,我这边写了一个解决自己框架依赖的方法;
1.首先做准备工作:初始化日志和储存接口响应体的map;
pom依赖:
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
初始化代码:
private static Logger log = Logger.getLogger(GetResultFieldsValues.class);//初始化日志
public static Map<String,Object> stockpileResultData = new HashMap<>();//储存每次api请求的响应体
public static Map<String,String> stockpileUri = new HashMap<>();//储存接口请求的uri路径
public static String getResultKey; //赋值字段名,获取result中的变量
2.编写获取数据的工具类:
2.1拆分url,获取响应体:
1)拆分url:获取接口请求的uri路径.
2)从响应体中获取data,添加到map.
/**
* 1.拆分url,获取api请求路径
* 2.添加api请求的响应体数据到map
* @param url 接口请求地址
* @param result 接口请求响应体
*/
public static void getUriAndResultPutMap(String url, String result) {
if (url != null) {
//url中包含的"?",区分get/post拆分方式
//从url中拆分uri
if (url.contains("?")) {
String subUrl = url.substring(0, url.indexOf("?"));
String[] splitUrl = subUrl.split("/");
url = splitUrl[splitUrl.length - 1];
stockpileResultData.put("uri",url);
} else {
String[] splitUrl = url.split("/");
url = splitUrl[splitUrl.length-1];
stockpileUri.put("uri",url);
}
}
//将result转为json格式数据,并取出data
JSONObject jsonData = (JSONObject) JSONObject.parseObject(result).get("data");
//data不为空则添加到map
if (jsonData != null) {
Map<String,Object> jsonMap = new HashMap(jsonData);
for (Object key : jsonMap.keySet()) {
if (key != null && jsonMap.get(key) != null) {
stockpileResultData.put(key.toString(),jsonMap.get(key));
}
}
}
//通过uri给设置getResultKey的赋值
setFieldsVlues();
}
2.2根据拆分出的uri,给变量getResultKey赋值;
注:因为我这边是迎合自己框架写的方法,switch只写一个case,友友们参数多需要自己做更改哦!
/**
* 根据uri地址,设置getResultKey的值
*/
public static void setFieldsVlues() {
Set<Map.Entry<String, String>> entries = stockpileUri.entrySet();
for (Map.Entry<String,String> uri : entries) {
switch (uri.getValue()) {
//login-by-mobile是拆分出的uri地址
case "login-by-mobile":
getResultKey="role";
break;
default:
log.error("没有找到变量");
break;
}
}
}
2.2编写一个静态方法返回map:
1)取出上一步储存在map中的数据.
2)并返回一个map,用于编写自动化用例时,添加到params.
/**
* 获取上游接口参数,解决接口依赖
* @return
*/
public static Map<String,Object> getResultvalue() {
//定义map用于返回获取的值
Map<String, Object> resultMap = new HashMap<>();
String jsonMap = JSON.toJSONString(stockpileResultData);
JSONObject jsonResult = JSONObject.parseObject(jsonMap);
try {
Object getValue = jsonResult.get(getResultKey);
if (getValue != null) {
resultMap.put(getResultKey,getValue);
}
} catch (NullPointerException e) {
log.error("空指针异常,请检查获取的响应体中的字段名!");
}
return resultMap;
}
2.3准备好已经写的post请求类:
1)将2.1写好的静态方法在**doPost_json**中引用;
/**
* post请求:处理 json 格式参数
* @param url 接口请求地址
* @param params 接口请求参数
* @return
*/
@RequestWrapper()
public static String doPost_json(String url, Map<String, Object> params) {
//指定请求方式
HttpPost httpPost = new HttpPost(url);
//指定请求头
httpPost.addHeader("User-agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36");
httpPost.addHeader("Content-Type","application/json");
httpPost.addHeader("platformCode","weixin");
//根据获取得数据,添加请求头
addCookieInRequestHeaderBeforeRequest(httpPost);
//将参数转为json格式
JSONObject jsonObject = new JSONObject(params);
StringEntity stringEntity = new StringEntity(jsonObject.toString(),"UTF-8");
CloseableHttpResponse response = null;
CloseableHttpClient client = null;
String result = null;
try {
httpPost.setEntity(stringEntity);
client = HttpClients.createDefault();
//发起请求,获取接口响应信息(状态码,响应报文,或某些特殊的响应头数据)
response = client.execute(httpPost);
//判断请求头中是否带有Set-cookie
getAndStoreCookiesFromResponseHeader(response);
//获取状态码
int statusCode = response.getStatusLine().getStatusCode();
//获取响应体
result = EntityUtils.toString(response.getEntity());
//拆分url获取api路径,
getUriAndResultPutMap(url,result);
log.info("状态码->[" + statusCode + "],响应报文->[" + result + "]");
//判断result中的返回结果是否带有token
getResultToken(result);
if (!("200".equals(String.valueOf(statusCode)))){
log.warn("请求失败,当前状态码:" + statusCode);
log.warn("请求参数:" + params);
}
} catch (Exception e) {
log.error("运行时异常,报错内容:" + e);
} finally {
//资源关闭
try {
if (client != null) {
log.info("关闭当前client连接");
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (response != null) {
log.info("关闭当前response连接");
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//返回响应结果
return result;
}
3.开始小实验,对api发起请求:
public static void main(String[] args) {
String url = "http://*********";
Map<String,Object> params = new HashMap<>();
params.put("mobile","*********");
params.put("smsCode","****");
doPost_json(url,params);
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++");
Map<String, Object> resultvalue = getResultvalue();
if (resultvalue.size() > 0) {
for (Map.Entry<String, Object> data : resultvalue.entrySet()) {
params.put(data.getKey(), data.getValue());
}
System.out.println(params);
}
String result = doPost_json(url, params);
}
惊心动魄的时刻来了,让我们以图片的形式见证:
第一次请求的body:{smsCode=8888, mobile=1560001}
第二次请求的body,获取的上次请求的参数:{role=2, smsCode=8888, mobile=15600015}
4.杂谈:
其实也不用我这样的复杂,通过马爸爸的fastjson框架,将响应体转为json格式,两行代码取两次也能拿出响应体中下游接口需要依赖的参数,定义一个map储存,在写自动化用例时,取出来添加到我们的测试数据中。
因为本菜菜编码能力较弱,望各位大佬勿喷,本文只做交流,忘大佬们给予菜菜宝贵的意见~。