[JsonSchema] 關於接口測試 Json 格式比對核心算法實現 (Java 版)

引言

爲什麼要自己重新造輪子,而不是採用第三方的JsonSchema方法進行實現
存在以下痛點:
1.我之前在網上找了很久,沒有找到java版直接進行jsonschema生成的方法或直接比較的方法
2.http://JSONschema.net/#/home 使用這塊框架,必須要先把我們的Json信息複製到該網頁,然後通過該網頁生成的jsonschema格式文件寫到本地,效率實在過於低下
3.其次我相信很多人都已經實現這塊方法,但一直沒有開源出來,在此小弟做個拋磚引玉

設計思路

1.比較JSON的Value值是否匹配(在我個人看來有一定價值,但還不夠,會引發很多不必要但錯誤)
2.能比較null值,比如 期望json中某個值是有值的,而實際json雖然存在這個key,但它的value是null
3.能比較key值是否存在
4.能比較jsonArray;

其中針對jsonArray要展開說明下;
1.對於jsonArray內所有的jsonObject數據肯定是同一類型的,因此我這邊做的是隻比較jsonArray的第一個JsonObject
2.對於jsonArray,大家可能會關心期望長度和實際長度是否有差異

總的而言,採用遞歸思路進行實現

現在直接附上代碼,已實現generateJsonSchema方法直接把json信息 轉換成jsonschema,再結合比對函數diffFormatJson,自動校驗jsonschema

package com.testly.auto.core;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.junit.Test;

import java.util.Iterator;

/**
 * Created by 古月隨筆 on 2017/6/23.
 */
public class DiffMethod {

   /**
     * 返回當前數據類型
     * @param source
     * @return
     */
    public String getTypeValue(Object source){

        if(source instanceof String){
            return "String";
        }

        if(source instanceof Integer){
            return "Integer";
        }

        if(source instanceof Float){
            return "Float";
        }

        if(source instanceof Long){
            return "Long";
        }

        if(source instanceof Double){
            return "Double";
        }

        if(source instanceof Date){
            return "Date";
        }

        if(source instanceof Boolean){
            return "Boolean";
        }

        return "null";
    }


    /**
     * 把Object變成JsonSchema
     * @param source
     * @return
     */
    public Object generateJsonSchema(Object source){

        Object result = new Object();

        //判斷是否爲JsonObject
        if(source instanceof JSONObject){
            JSONObject jsonResult = JSONObject.fromObject(result);
            JSONObject sourceJSON = JSONObject.fromObject(source);
            Iterator iterator = sourceJSON.keys();
            while (iterator.hasNext()){
                String key = (String) iterator.next();
                Object nowValue = sourceJSON.get(key);

                if(nowValue == null || nowValue.toString().equals("null")){
                    jsonResult.put(key,"null");

                }else if(isJsonObject(nowValue)){
                    jsonResult.put(key,generateJsonSchema(nowValue));
                }else if(isJsonArray(nowValue)){
                    JSONArray tempArray = JSONArray.fromObject(nowValue);
                    JSONArray newArray = new JSONArray();

                    if(tempArray != null && tempArray.size() > 0 ){
                        for(int i = 0 ;i < tempArray.size(); i++){
                            newArray.add(generateJsonSchema(tempArray.get(i)));
                        }
                        jsonResult.put(key,newArray);
                    }
                }else if(nowValue instanceof List){
                    List<Object> newList = new ArrayList<Object>();

                    for(int i = 0;i<((List) nowValue).size();i++){
                        newList.add(((List) nowValue).get(i));
                    }

                    jsonResult.put(key,newList);
                }else {

                    jsonResult.put(key,getTypeValue(nowValue));
                }

            }
            return jsonResult;
        }


        if(source instanceof JSONArray){
            JSONArray jsonResult = JSONArray.fromObject(source);
            JSONArray tempArray = new JSONArray();
            if(jsonResult != null && jsonResult.size() > 0){
                for(int i = 0 ;i < jsonResult.size(); i++){
                    tempArray.add(generateJsonSchema(jsonResult.get(i)));
                }
                return tempArray;
            }

        }

        return getTypeValue(source);

    }



    /**
     * JSON格式比對
     * @param currentJSON
     * @param expectedJSON
     * @return
     */
    public JSONObject diffJson(JSONObject currentJSON,JSONObject expectedJSON){

        JSONObject jsonDiff = new JSONObject();

        Iterator iterator = expectedJSON.keys();

        while (iterator.hasNext()){
            String key = (String)iterator.next();
            Object expectedValue = expectedJSON.get(key);
            Object currentValue = currentJSON.get(key);
            if(!expectedValue.toString().equals(currentValue.toString())){
                JSONObject tempJSON = new JSONObject();
                tempJSON.put("value",currentValue);
                tempJSON.put("expected",expectedValue);
                jsonDiff.put(key,tempJSON);
            }
        }
        return jsonDiff;
    }


    /**
     * 判斷是否爲JSONObject
     * @param value
     * @return
     */
    public boolean isJsonObject(Object value){

        try{
            if(value instanceof JSONObject) {
                return true;
            }else {
                return false;
            }
        }catch (Exception e){
            return false;
        }
    }


    /**
     * 判斷是否爲JSONArray
     * @param value
     * @return
     */
    public boolean isJsonArray(Object value){

        try{

            if(value instanceof JSONArray){
                return true;
            }else {
                return false;
            }

        }catch (Exception e){
            return false;
        }
    }


    /**
     * JSON格式比對,值不能爲空,且key需要存在
     * @param current
     * @param expected
     * @return
     */
    public JSONObject diffFormatJson(Object current,Object expected){

        JSONObject jsonDiff = new JSONObject();

        if(isJsonObject(expected)) {

            JSONObject expectedJSON = JSONObject.fromObject(expected);
            JSONObject currentJSON = JSONObject.fromObject(current);

            Iterator iterator = JSONObject.fromObject(expectedJSON).keys();

            while (iterator.hasNext()) {
                String key = (String) iterator.next();
                Object expectedValue = expectedJSON.get(key);

                if (!currentJSON.containsKey(key)) {
                    JSONObject tempJSON = new JSONObject();
                    tempJSON.put("actualKey", "不存在此" + key);
                    tempJSON.put("expectedKey", key);
                    jsonDiff.put(key, tempJSON);

                }

                if (currentJSON.containsKey(key)) {

                    Object currentValue = currentJSON.get(key);

                    if (expectedValue != null && currentValue == null || expectedValue.toString() != "null" && currentValue.toString() == "null") {
                        JSONObject tempJSON = new JSONObject();
                        tempJSON.put("actualValue", "null");
                        tempJSON.put("expectedValue", expectedValue);
                        jsonDiff.put(key, tempJSON);
                    }

                    if (expectedValue != null && currentValue != null) {
                        if (isJsonObject(expectedValue) && !JSONObject.fromObject(expectedValue).isNullObject() || isJsonArray(expectedValue) && !JSONArray.fromObject(expectedValue).isEmpty()) {
                            JSONObject getResultJSON = new JSONObject();
                            getResultJSON = diffFormatJson(currentValue, expectedValue);
                            if (getResultJSON != null) {
                                jsonDiff.putAll(getResultJSON);
                            }
                        }
                    }
                }
            }
        }

        if(isJsonArray(expected)){
            JSONArray expectArray = JSONArray.fromObject(expected);
            JSONArray currentArray = JSONArray.fromObject(current);

            if(expectArray.size() != currentArray.size()){
                JSONObject tempJSON = new JSONObject();
                tempJSON.put("actualLenth",currentArray.size());
                tempJSON.put("expectLenth",expectArray.size());
                jsonDiff.put("Length",tempJSON);
            }

            if(expectArray.size() != 0){
                Object expectIndexValue = expectArray.get(0);
                Object currentIndexValue = currentArray.get(0);

                if(expectIndexValue != null && currentIndexValue != null){
                    if (isJsonObject(expectIndexValue) && !JSONObject.fromObject(expectIndexValue).isNullObject() || isJsonArray(expectIndexValue) && !JSONArray.fromObject(expectIndexValue).isEmpty()) {
                        JSONObject getResultJSON = new JSONObject();
                        getResultJSON = diffFormatJson(currentIndexValue, expectIndexValue);
                        if (getResultJSON != null) {
                            jsonDiff.putAll(getResultJSON);
                        }
                    }
                }
            }
        }

        return jsonDiff;
    }
}

測試驗證:


    public static void main(String[] args) {

        DiffMethod diffMethod = new DiffMethod();


        String str1 = "{\"status\":201,\"msg\":\"今天您已經領取過,明天可以繼續領取哦!\",\"res\":{\"remainCouponNum\":\"5\",\"userId\":\"123123213222\"}}";

        JSONObject jsonObject1 = JSONObject.fromObject(str1);


        String str2 = "{\"status\":201,\"msg2\":\"今天您已經領取過,明天可以繼續領取哦!\",\"res\":{\"remainCouponNum\":\"5\",\"userId\":\"123123213222\"}}";

        JSONObject jsonObject2 = JSONObject.fromObject(str2);


        String str3 = "{\"status\":null,\"msg\":\"今天您已經領取過,明天可以繼續領取哦!\",\"res\":{\"remainCouponNum\":\"5\",\"userId\":\"123123213222\"}}";

        JSONObject jsonObject3 = JSONObject.fromObject(str3);

        System.out.println("轉換成JSONschame:" + diffMethod.generateJsonSchema(jsonObject1).toString());


        System.out.println("當前str2沒有msg字段: " + diffMethod.diffFormatJson(jsonObject2,jsonObject1).toString());

        System.out.println("當前str2中的status爲null值:" + diffMethod.diffFormatJson(jsonObject3,jsonObject1).toString());


    }

測試結果:

轉換成JSONschame:{"status":"Integer","msg":"String","res":{"remainCouponNum":"String","userId":"String"}}
當前str2沒有msg字段: {"msg":{"actualKey":"不存在此msg","expectedKey":"msg"}}
當前str2中的status爲null值:{"status":{"actualValue":null,"expectedValue":201}}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章