[JsonSchema] 关于接口测试 Json 格式比对核心算法实现 (Java 版)

时间:2023-03-08 16:44:48
[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}}
[JsonSchema] 关于接口测试 Json 格式比对核心算法实现 (Java 版)