在真正开始接口测试之前,我们需要对参数的处理进行梳理。这里所说的“参数”,既包含之前在xml中的配置(我们称之为全局参数),也包含在每一条用例中书写的param。全局参数为固定不变的,而根据接口相应获取的数据是动态变化的。
  之前我们已经用${param_name}的形式,定义了如何从公共参数池中调用所需要的参数。
       并且当一个接口的请求发送完成,进行下一个接口操作的时候,我们也需要对相应的数据进行处理。例如,前面一个接口的响应中出现了下一个接口需要使用的数据,比如id,password,token等等。那么需要对这些数值进行操作(保存·),把获取到的数据存入这个公共参数池中,然后在后续的接口请求中调用这些数据。
  对于作为测试用例数据的格式,我们可以把它设计成这样的。

在这里,我们可以看到,在url,header,param中,我们使用了${param_name}的形式,这些变量可以从我们的公共参数池中取得,而后面的verify,可以对返回值使用JSONPath来精准判定。而对于,save中的内容,我们可以将其存入公共参数池,供后面的接口进行调用。

  接下来,我们逐步来作成TestBase的基础类,在这个类中,我们来逐步定义如何处理参数以及如何来使用参数。在这个类中,牵涉到很多关联调用的其他工具类,在本篇中暂时不做说明。在之后的章节中来逐步去说明调用关系。
  PS:在我们写一个程序时,如果一时不能把程序的构造想清楚,可以先用自然语言把整体逻辑描述清楚,具体的代码可以之后再进行斟酌。
  首先,我们先需要定义一个公共参数池,以及对应与${param_name}的正则表达式。
 

    /**
* 公共参数数据池(全局可用)
*/
private static Map<String, String> saveDatas = new HashMap<String, String>(); /**
* 替换符,如果数据中包含“${}”则会被替换成公共参数中存储的数据
*/
protected Pattern replaceParamPattern = Pattern.compile("\\$\\{(.*?)\\}"); /**
* 获取公共数据池中的数据
*
* @param key
* 公共数据的key
* @return 对应的value
*/
protected String getSaveData(String key) {
if ("".equals(key) || !saveDatas.containsKey(key)) {
return null;
} else {
return saveDatas.get(key);
}
}
protected void setSaveDatas(Map<String, String> map) {
saveDatas.putAll(map);
}

  在使用过程中,我们可以将参数分为两类。第一类为全局参数,意思是可以将之前从xml中读取的配置,作为全局参数存入公共参数数据池,在整个接口测试运行的过程中均可进行调用。第二类是,接口过程中产生对的过程参数,即,接口A返回的数据,可以作为参数使用在接口B的请求中。这类参数在接口请求执行过程中进行定义,也存入公共参数池。

  这两类参数,均使用${param_name}的形式进行调用。来看下面一段代码:

    /**
* 取公共参数 并替换参数,处理${}
* @param param
* @return
*/
protected String getCommonParam(String param) {
if (stringUtil.isEmpty(param)) { //stringUtil后续进行说明
return "";
}
Matcher m = replaceParamPattern.matcher(param);// 取公共参数正则
while (m.find()) {
String replaceKey = m.group(1);
// 如果公共参数池中未能找到对应的值,该用例失败。
Assert.assertNotNull(replaceKey,
String.format("格式化参数失败,公共参数中找不到%s。", replaceKey));
String value;
// 从公共参数池中获取值
value = getSaveData(replaceKey);
//如果值不为空,则将参数替换为公共参数池里读取到的value的值。
if(null != value) {
param = param.replace(m.group(), value);
//如果值为空,则将参数替换为字符串“null”
}else {
param = param.replace(m.group(), "null");
}
}
return param;
}

  这里使用了正则表达式来匹配参数中出现的${XXXX}形式的字符串。这一段的主要思想为,使用定义好的正则表达式来匹配param的字符串,如果匹配的到,则进行循环,把匹配到的第一个字符串(基本就是1个字符串)作为key,然后到saveData的Map中取得对应的值,并返回。

  这样,我们就实现了使用${param_name}的形式,调用公共参数池的目的。

  那么说完了“取参数”,我们还需要说一下“存参数”。在接口测试执行的过程中,假如我想把某个返回的值作为参数,存入公共参数池中,我们应该怎么做呢?

    /**
* 提取json串中的值保存至公共池中
*
* @param json
* 将被提取的json串。
* @param allSave
* 所有将被保存的数据:xx=$.jsonpath.xx;将$.jsonpath.
* xx提取出来的值存放至公共池的xx中
*/
protected void saveResult(String json, String allSave) {
if (null == json || "".equals(json) || null == allSave
|| "".equals(allSave)) {
return;
}
allSave = getCommonParam(allSave);
String[] saves = allSave.split(";");
String key, value;
for (String save : saves) {
Pattern pattern = Pattern.compile("([^;=]*)=([^;]*)");
Matcher m = pattern.matcher(save.trim());
while (m.find()) {
key = getBuildValue(json, m.group(1)); //getBuildValue的方法后续说明
value = getBuildValue(json, m.group(2));
reportUtil.log(String.format("存储公共参数 %s值为:%s.", key, value));
saveDatas.put(key, value);
}
}
}

  这里我们在save时,同样是通过正则表达式来进行匹配,具体的形式类似于 aa=$.Content.User 的形式,即变量名=JSONPath,将JSONPath找到的值来赋此变量,并存储到公共参数池中。

  这里提到了一个getBuildValue的方法,具体的代码如下:

/**
* 获取格式化后的值
*
* @param sourchJson
* @param key
* @return
*/
private String getBuildValue(String sourchJson, String key) {
key = key.trim();
Matcher funMatch = funPattern.matcher(key); //funPattern为函数匹配正则表达式,后续进行说明
if (key.startsWith("$.")) {// 如果为JSONPath,获取该JSONPath对应的值(对象)
Object x = JSONPath.read(sourchJson, key);
       //空值处理
if(x == null) {
key = (String)x;
}else {
key = x.toString();
}
       //如果匹配到的是自定义函数,则先解析该自定义函数的参数,若该自定义函数的参数中有JSONPath,则对该JSONPath取值,并对应转成字符串对象。
} else if (funMatch.find()) {
String args = funMatch.group(2);
String[] argArr = args.split(",");
for (int index = 0; index < argArr.length; index++) {
String arg = argArr[index];
if (arg.startsWith("$.")) {
argArr[index] = JSONPath.read(sourchJson, arg).toString();
}
}
String value = functionUtil.getValue(funMatch.group(1), argArr); // functionUtil为自定义函数工具类,后续说明
key = stringUtil.replaceFirst(key, funMatch.group(), value);
}
return key;
}

  那么,通过以上的代码,我们可以较为清晰的看到,我们设计了这个公共参数池,来对全局参数和过程参数进行管理,即可取也可存。方便了在之后的代码中进行调用。

  在上面的代码中,我们出现了一个stringUtil的工具类,这算是一个字符串处理工具。请看以下代码:

public class stringUtil {
public static boolean isNotEmpty(String str) {
return null != str && !"".equals(str);
} public static boolean isEmpty(String str) {
return null == str || "".equals(str);
} /**
*
* @param sourceStr 待替换字符串
* @param matchStr 匹配字符串
* @param replaceStr 目标替换字符串
* @return
*/
public static String replaceFirst(String sourceStr,String matchStr,String replaceStr){
int index = sourceStr.indexOf(matchStr);
int matLength = matchStr.length();
int sourLength = sourceStr.length();
String beginStr = sourceStr.substring(0,index);
String endStr = sourceStr.substring(index+matLength,sourLength);
sourceStr = beginStr + replaceStr + endStr;
return sourceStr;
} }

  这个工具类中,写了判定字符串是否为空的方法,还有一个替换首个匹配字符串的方法。有兴趣的童鞋可以自行继续扩展。

  
  

基于Java+HttpClient+TestNG的接口自动化测试框架(四)-------参数存取处理的更多相关文章

  1. 基于Java+HttpClient+TestNG的接口自动化测试框架(八)------ 针对文件的处理

    在实际的接口测试中,有时需要根据情况进行文件的上传和下载.在文件数量比较小的时候,我们当然可以直接处理(比如若干个接口都用一个文件).但是,如果我们上传的文件需要使用不同文件夹里不同的文件,而且数量又 ...

  2. Python 基于python实现的http接口自动化测试框架(含源码)

    基于python实现的http+json协议接口自动化测试框架(含源码) by:授客 QQ:1033553122      欢迎加入软件性能测试交流 QQ群:7156436  由于篇幅问题,采用百度网 ...

  3. 手把手教你用Eclipse+TestNG搭建接口自动化测试框架

    转载于:http://qa.blog.163.com/blog/static/190147002201510275306185/ 把群博里关于接口自动化的文章都看了一遍,都是关于测试过程中遇到的问题及 ...

  4. Eclipse+TestNG搭建接口自动化测试框架

    一.环境安装 1.前提 安装好jdk 配置好Java环境变量 安装Eclips 这些网上都有,就不再详细介绍. 资源分享链接:http://pan.baidu.com/s/1v9Fw6 2.安装Tes ...

  5. 基于Python + requests 的web接口自动化测试框架

    之前采用JMeter进行接口测试,每次给带新人进行培训比较麻烦,干脆用python实现,将代码和用例分离,易于维护. 项目背景 公司的软件采用B/S架构,进行数据存储.分析.管理 工具选择 pytho ...

  6. 接口自动化 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)

    基于python实现的http+json协议接口自动化测试框架(实用改进版)   by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436     目录 1.      ...

  7. Python 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)

    目录 1.      写在前面 2.      开发环境 3.      大致流程 4.      框架简介 5.      运行结果展示 6.      文件与配置 7.      测试接口实例 n ...

  8. 接口自动化测试框架 -- reudom

    reudom Automated testing framework based on requests and unittest interface. 基于 Unittest 和 Requests ...

  9. 基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport的接口自动化测试框架

    接口自动化框架 项目说明 本框架是一套基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport而设计的数据驱动接口自动化测试框架,TestNG ...

随机推荐

  1. InetAddress与Socket

    InetAddress:构造方法私有,不能直接创建对象. InetAddress getByName(String host):在给定主机名的情况下确定主机的ip地址. InetAddress get ...

  2. MockMvc control层单元测试 参数传递问题

    GET: 1.路径参数@PathVariable 2.表单参数@RequestParam POST: 1.JSON请求体参数 @RequestBody 放: 1.路径参数@PathVariable 2 ...

  3. Vue中通过属性绑定为元素绑定style行内样式

    1.直接在元素上通过:style的形式,书写样式对象 2.将样式对象定义在data中,并直接引用到:style中 3.在:style中通过数组,引用多个data上的样式对象

  4. computed计算属性(二)

    一.说明 在computed中,可以定义一些属性,即计算属性. 计算属性本质是方法,只是在使用这些计算属性的时候,把他们的名称直接当作属性来使用,并不会把计算属性当作方法去调用,不需要加小括号()调用 ...

  5. webpack+babel+react+antd技术栈的基础配置

    webpack+babel+react+antd技术栈的基础配置 前段时间使用webpack+babel+react+antd做了一套后台管理系统,刚开始被一大堆的新知识压的喘不过气来,压力挺大的.还 ...

  6. dotnet core 使用 GBK 编码

    本文告诉大家如何在 .NET Core 中使用 GBK 编码 默认的 .NET Core 框架不包含 GBK 编码,不包含除了代码页为 28591 和 Unicode(utf-8,utf-16) 之外 ...

  7. HDU - 3530 Subsequence (单调队列)

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. win10 uwp 录制任意应用屏幕

    在 1803 可以使用 Windows.Graphics.Capture 捕获屏幕,可以用来录制应用的窗口 通过 CompositionAPI 和 win2d 可以作为 D3D 绘制,通过 Direc ...

  9. Trendalyzer is an information visualization software

    Trendalyzer is an information visualization software for animation of statistics that was initially ...

  10. Java 学习笔记(16)——Java数据库操作

    数据库操作是程序设计中十分重要的一个部分,Java内置JDBC来操作数据库 JDBC使用 JDBC--Java Database connecting Java数据库连接:本质上JDBC定义了操作数据 ...