基於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

相關文章
相關標籤/搜索