在真正开始接口测试之前,我们需要对参数的处理进行梳理。这里所说的“参数”,既包含之前在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. 人脸检测MTCNN的训练过程(PRO网络)

    以下学习均由此:https://github.com/AITTSMD/MTCNN-Tensorflow 数据集 WIDER Face for face detection and Celeba for ...

  2. java编译器优化和运行期优化

    概述    最近在看jvm优化,总结一下学习的相关知识 (一)javac编译器 编译过程 1.解析与填充符号表过程 1).词法.语法分析    词法分析将源代码的字符流转变为标记集合,单个字符是程序编 ...

  3. vue依赖

    ajax:vue-resource moke数据:body-parser

  4. VisualStudio 2019 新特性

    很多小伙伴都好奇 VisualStudio 2019 有哪些功能,下面让我介绍一些好玩的特性 在安装完成之后会看到创新的欢迎界面,这个欢迎界面支持输入关键字搜项目,同时支持选择语言平台 很多小伙伴都说 ...

  5. 从物联网设备生命周期理解Apple Homekit框架

    本次笔记主要基于苹果公开的HomeKit Accessory Protocol协议文档和IOS Security Guide中相关部分. 总体来讲,设备与App之间采用端到端的加密,密钥由设备和App ...

  6. .NET Core + docker入门

    下载安装docker docker客户端,今天vpn小水管实在是受不了,于是找了国内的下载地址 配置docker加速器 参考博文Docker for windows10 配置阿里云镜像 docker入 ...

  7. Android Library的依赖方式及发布(转)

    还是那句老话,好记性不然烂笔头,在此整理 Android Studio 依赖相关 以及 如何发布项目到 JCenter Android Studio 添加依赖Module 依赖module 依赖是指在 ...

  8. QP简介

    QP简介 QP(Quantum Platform)是一个轻量级的.开源的.基于状态机的.事件驱动型应用程序框架.这个框架包括四部分: 事件处理器(QEP): 轻量级的事件驱动框架(QF): 任务调度微 ...

  9. CodeForces 1182D

    图论的思维题,太秀了,网上答案也不多,我就也来bb吧 总之47个样例姑且是过了,不知道还有没有反例: 会求树的重心和中心了,挺好 #include<cstdio> #include< ...

  10. 浪潮服务器装linux系统无法识别硬盘

    先说无法识别硬盘的原因是没有安装和系统相对应的raid驱动. 公司需要两台Linux的物理服务器来部署业务系统. 客户给了两台浪潮的服务器. 1.先把linux系统刻录到u盘 2要先看一下raid卡的 ...