Java實現 Json、String、Integer等對象的數據一致性的精確比對


Java實現 Json、String、Integer等對象的數據一致性的精確比對

我們在接口自動化測試過程中,或多或少會遇到當比較接口返回結果時,如果將結果作為一個整體的對象進行比較,假如斷言失敗時,那我們將會看到一大坨期望和實際結果數據,很難一眼就看出具體是因為哪一部分不一致而導致的比對失敗,這也增加了我們的接口自動化維護成本。

本文主要圍繞這一痛點,解決 JsonObject、JSONArray、String、Integer 對象的精確比較問題,並提供統一的Java實現方法 Compare.CompareFactory,希望對大家有所幫助。

先睹為快,讓我們直接來看下效果如何,此外,文末附 Python 具體實現設計。

JSONObject 對象的一致性比對

如下,先準備兩個測試數據,我們可以看到測試數據的結構還是比較複雜的,其中左側和右側不一致的地方共有7處,如黃色框處的位置。

Java實現 Json、String、Integer等對象的數據一致性的精確比對

首先看一下,如果直接斷言,我們看到的結果是什麼樣的。

Java實現 Json、String、Integer等對象的數據一致性的精確比對

正如開篇所提,想要找出其中的不同,實在... 簡直... 。

然後,使用 Compare.CompareFactory 方法,執行過程中的打印結果如下,我們可以看到每個節點的比較結果都非常清晰的打印出來了,並且key 的描述也是含

JSON層級關係的,如 "regional.city[0]"


Java實現 Json、String、Integer等對象的數據一致性的精確比對

再然後,看下 Compare.CompareFactory 方法的返回結果,我們將返回對象使用JSONObject.toJSONString 轉換成字符串後,如下,resultDetail 屬性記錄了每個錯誤節點的期望和實際數據值,

wrongNumber 屬性統計了錯誤數量,清晰明瞭,簡單直白。

Java實現 Json、String、Integer等對象的數據一致性的精確比對

最後,看下代碼,因為我將測試數據放到 yaml 文件中,因為其中部分代碼是在加載測試數據。

Java實現 Json、String、Integer等對象的數據一致性的精確比對



JSONArray 對象的一致性比對

首先,準備如下兩個測試數據,其中左側和右側不一致的地方共有 5 處,如黃色框處的位置。

Java實現 Json、String、Integer等對象的數據一致性的精確比對

然後,使用 Compare.CompareFactory

方法,執行過程中的打印結果如下:

Java實現 Json、String、Integer等對象的數據一致性的精確比對

再然後,我們看下 Compare.CompareFactory 方法的返回結果,如下:

Java實現 Json、String、Integer等對象的數據一致性的精確比對

最後,我們看下示例代碼,因為我將測試數據放到Yaml文件中,所以其中部分代碼是在加載測試數據。

Java實現 Json、String、Integer等對象的數據一致性的精確比對



String、Integer、Long 對象的一致性比對

String、Integer、Long 對象的比對,同樣也是使用 Compare.CompareFactory 方法完成,示例代碼如下:

Java實現 Json、String、Integer等對象的數據一致性的精確比對


因為String、Integer、Long不存在KV映射,因此比較結果中key顯示為null。如下:


Java實現 Json、String、Integer等對象的數據一致性的精確比對


還提供了哪些特性?

肯定有小夥伴會問,在做接口返回結果的校驗時,並不是全部的數據都需要一一進行比對,比如時間屬性,因為每次可能返回的時間不同,但本身不影響結果的準確性,所以不需要進行比較。 那Compare.CompareFactory 方法是否不支持過濾某些屬性不比較呢?——那當然是支持的咯,細心的小夥伴 Compare.CompareFactory 的有三個參數,那第三個是幹嘛的呢?其實第三個參數就是描述需要過濾的屬性的,如果需要過濾多個屬性使用英文逗號隔開即可。

Java實現 Json、String、Integer等對象的數據一致性的精確比對

比如,我們將上圖例子中的實際和期望結果不一致的 code、designation、hobby_id、desc 4個屬性過濾掉不比較,代碼如下。

Java實現 Json、String、Integer等對象的數據一致性的精確比對

運行代碼,我們可以看到比對結果中,只存在三處不一致的地方,即實現了過濾比較。

Java實現 Json、String、Integer等對象的數據一致性的精確比對



核心源碼

最後,如何獲取全部源碼? 因文章無法上傳Git鏈接,需要源碼的小夥伴可以私聊我,記得關注、點贊支持一下哦。

因涉及多個java文件,這裡只能貼出核心代碼,如下:

<code> import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONArray;
 import org.apache.commons.lang3.StringUtils;
 
 public class Compare {
     private static BaseResult baseResult;
 ​
     /**
      * @Description: 更新結果,錯誤數量計數
      * @Param: [parameter]
      * @Author:
      * @DateTimeFormat: 2020/3/8
      */
     private static void updateBaseResult(ResultDetail resultDetail) {
         // 錯誤數量統計
         baseResult.setWrongNumber(baseResult.getWrongNumber() + 1);
 ​
         // 填充 RetValue 錯誤內容
         if (baseResult.getResultDetail() == null) {
             ArrayList<resultdetail> resultDetailArrayList = new ArrayList<resultdetail>();
             resultDetailArrayList.add(resultDetail);
             baseResult.setResultDetail(resultDetailArrayList);

        } else {
             baseResult.getResultDetail().add(resultDetail);
        }
    }
 ​
     /**
      * @Description: 字符串比較
      * @Param: [parameter]
      * @return: void
      * @Author: YJiang
      * @DateTimeFormat: 2020/3/8
      */
     private static void compareJson(String actualString, String expectString, String key, String prefix , String ignore) {
         boolean status = false;
         if (StringUtils.isNotBlank(ignore)) {
             List<string> listIgnore = Arrays.asList(ignore.split(","));
             status = listIgnore.contains(key);
        }
         if (!status) {
             if (!actualString.equals(expectString)) {
                 ResultDetail resultDetail = new ResultDetail(prefix, actualString, expectString, "Value Not Equal");
                 updateBaseResult(resultDetail);
                 System.out.println(
                         "\\033[1;31m" + "【fail】Key:" + prefix + "\\n     actualJson:" + actualString + "\\n     expectJson:" + expectString + "\\033[m");
 ​
            } else {
                 System.out.println(
                         "\\033[1;94m" + "【success】Key:" + prefix + "\\n     actualJson:" + actualString + "\\n     expectJson:" + expectString + "\\033[m");
            }
        }
    }
 ​
     /**
      * @Description: JSONObject 比較
      * @Param: [parameter]
      * @return: void
      * @Author: YJiang
      * @DateTimeFormat: 2020/3/8
      */
     private static void compareJson(JSONObject actualJson, JSONObject expectJson, String key,String prefix, String ignore) {
         if (StringUtils.isBlank(prefix)){
             prefix = "";
        }else {
             prefix = prefix + ".";
        }
 ​
         for (String s : expectJson.keySet()) {
             key = s;
             compareJson(actualJson.get(key), expectJson.get(key), key, prefix + key, ignore);
        }

    }
 ​
     /**
      * @Description: JSONArray 比較
      * @Param: [parameter]
      * @return: void
      * @Author: YJiang
      * @DateTimeFormat: 2020/3/8
      */
     private static void compareJson(JSONArray actualJsonArray, JSONArray expectJsonArray, String key,String prefix, String ignore) {
         if (actualJsonArray != null && expectJsonArray != null) {
             if (actualJsonArray.size() == expectJsonArray.size()) {
                 Iterator iteratorActualJsonArray = actualJsonArray.iterator();
                 if (StringUtils.isBlank(prefix)){
                     prefix = "";
                }
                 int num = 0;
                 for (Object o : expectJsonArray) {
                     compareJson(iteratorActualJsonArray.next(), o, key,prefix+"["+num+"]", ignore);
                     num ++;
 ​
                }
            } else {
                 ResultDetail resultDetail = new ResultDetail(prefix, actualJsonArray, expectJsonArray, "Length Not Equal");
                 updateBaseResult(resultDetail);
            }
        } else {
             if (actualJsonArray == null && expectJsonArray == null) {
                 ResultDetail resultDetail = new ResultDetail(prefix, "在 actualJsonArray 中不存在",
                     "在 expectJsonArray 中不存在",
                     "Both Not Exist");
                 updateBaseResult(resultDetail);
            } else if (actualJsonArray == null) {
                 ResultDetail resultDetail = new ResultDetail(prefix, "在 actualJsonArray 中不存在", expectJsonArray,
                     "Other Exist");
                 updateBaseResult(resultDetail);
            } else {
                 ResultDetail resultDetail = new ResultDetail(prefix, actualJsonArray, "在 expectJsonArray 中不存在",
                         "Other Exist");
                 updateBaseResult(resultDetail);
            }
        }
 ​
    }
     /**
      * @Description: Object 比較
      * @Param: [parameter]
      * @return: void

      * @Author: YJiang
      * @DateTimeFormat: 2020/3/8
      */
     private static void compareJson(Object actualJson, Object expectJson, String key,String prefix, String ignore) {
         if (actualJson != null && expectJson != null) {
             if (actualJson instanceof JSONObject) {
                 compareJson((JSONObject)actualJson, (JSONObject)expectJson, key,prefix, ignore);
            } else if (actualJson instanceof JSONArray) {
                 compareJson((JSONArray)actualJson, (JSONArray)expectJson, key,prefix, ignore);
            } else if (actualJson instanceof String) {
                 try {
                     String actualJsonToStr = actualJson.toString();
                     String expectJsonToStr = expectJson.toString();
                     compareJson(actualJsonToStr, expectJsonToStr, key,prefix, ignore);
 ​
                } catch (Exception e) {
                     ResultDetail resultDetail = new ResultDetail(prefix, actualJson, expectJson, "String 轉換髮生異常 Key");
                     updateBaseResult(resultDetail);
                     e.printStackTrace();
                }
 ​
            } else {
                 compareJson(actualJson.toString(), expectJson.toString(), key,prefix, ignore);
            }
        } else {
             if (actualJson == null && expectJson == null) {
                 ResultDetail resultDetail = new ResultDetail(prefix, "在actualJson中不存在", "在expectJson中不存在",
                     "Both Not Exist");
                 updateBaseResult(resultDetail);
            } else if (actualJson == null) {
                 ResultDetail resultDetail = new ResultDetail(prefix, "在actualJson中不存在", expectJson, "Other Exist");
                 updateBaseResult(resultDetail);
            } else{
                 ResultDetail resultDetail = new ResultDetail(prefix, actualJson, "在expectJson中不存在", "Not Exist");
                 updateBaseResult(resultDetail);
            }
 ​
        }
 ​
    }
 ​
     /** 非線性安全
      * @Description: CompareFactory
      * @Param: [parameter]
      * @return: void
      * @Author: YJiang
      * @DateTimeFormat: 2020/3/8

      */
     public static BaseResult CompareFactory(T actual, T expect, String ignore) {
 ​
         Compare.baseResult = new BaseResult();
         Compare.compareJson(actual, expect, null,null, ignore);
 ​
         return Compare.baseResult;
    }
 ​
 }
 ​
/<string>/<resultdetail>/<resultdetail>/<code>



對了,之前寫過JSON 一致性比對的Python實現,有興趣的同學可以看一下哦 。


分享到:


相關文章: