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

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

 

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

  接下来,咱们逐步来做成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}的形式进行调用。来看下面一段代码:json

/** * 取公共参数 并替换参数,处理${} * @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找到的值来赋此变量,并存储到公共参数池中。jsonp

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

/** * 获取格式化后的值 * * @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; }

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

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

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; } }

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

  
  

原文出处:https://www.cnblogs.com/generalli2019/p/12212591.html

相关文章
相关标签/搜索