[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 版)的更多相关文章
- curl中通过json格式吧post值返回到java中遇到中文乱码的问题
首先是: curl中模拟http请求: curl -l 127.0.0.1:8080/spacobj/core/do?acid=100 -H "token:101hh" -H &q ...
- 如何把一些字符串用dict组织成json格式?(小算法)
说明: 1. 数据库中的一条记录取出来是这样的(直接复制):'value1','value2' ,'value3' 2. 我希望使用的数据格式是:{key1:'value1',key2:'value2 ...
- Java中将JSON格式的数据转换成对应的Bean、Map、List数据
简单说明: 为了方便数据在客户端及服务器端的传输,有时候我们会用一些比较方便组织的数据类型,比如json.xml等传给客户端,客户端也可以重新组织数据传回服务器端.JSON和XML提供了一套比较方便的 ...
- java 解析json格式数据(转)
2012-07-30 16:43:54| 分类: java | 标签:java json |举报|字号 订阅 有时候我们可能会用到json格式的数据进行数据的传输,那么我们怎么把接收到 ...
- robot framework 接口测试 http协议post请求json格式
robot framework 接口测试 http协议post请求json格式 讲解一个基础版本.注意区分url地址和uri地址. rf和jmeter在添加服务器地址也就是ip地址的时候,只能url地 ...
- 如何识别一个字符串是否Json格式
前言: 距离上一篇文章,又过去一个多月了,近些时间,工作依旧很忙碌,除了管理方面的事,代码方面主要折腾三个事: 1:开发框架(一整套基于配置型的开发体系框架) 2:CYQ.Data 数据层框架(持续的 ...
- SQLyog-直接导出JSON格式的数据
前言:以前做过的一个项目,有这样的一个需求使用搜索引擎来查询对应的区域信息,不过区域信息要先导出来,并且数据格式是JSON格式的,在程序中能实现这个需求,不过下面的这种方法更加的简单,通过 ...
- Web API删除JSON格式的文件记录
Insus.NET的系列Web Api学习文章,这篇算是计划中最后一篇了,删除JSON格式的文件记录.前一篇<Web Api其中的PUT功能演示>http://www.cnblogs.co ...
- jmeter随笔(1)-在csv中数据为json格式的数据不完整
昨天同事在使用jmeter遇到问题,在csv中数据为json格式的数据,在jmeter中无法完整的取值,小怪我看了下,给出解决办法,其实很简单,我们一起看看,看完了记得分享给你的朋友. 问题现象: 1 ...
随机推荐
- Promise的两种处理异步的方式
单个异步处理: let usedMemoryPromise = fetchUsedMemeory(); usedMemoryPromise.then(data => {...}) functio ...
- 【XAF问题】多个属性验证RuleUniqueValue
一.问题 1. 在XAF中如何验证多个属性唯一值? 二.解决方法 使用RuleCombinationOfPropertiesIsUnique [RuleCombinationOfPropertiesI ...
- 手动编译tomcat
0. 准备 (1) 配置好Java, 我这里使用的Oracle jdk 1.8.0_192; (2) 配置好Ant, 我这里使用的ant 1.10.5; (3) tomcat源代码, 我这里使用的 a ...
- c# winform Chart Pie 中若X轴数据为字符串时,#VALX取值为0
https://q.cnblogs.com/q/83848/ 在winform程序中用自带的Chart进行画图表时,若画饼图,其中X轴数据为字符串,这时候如果想设置Label值的格式为#VALX:#V ...
- Sql中如何将数据表的两个字段的值如何互换?
今天遇到一个数据表的两个列数据要互换,在网上找到并记录下. 直接用Sql就可以搞定,语法如下 --将数据表中两个列数据互换的语法-- update tabName set field1=field2, ...
- Java加密算法
密码的常用术语: 1.密码体制:由明文空间.密文空间.密钥空间.加密算法和解密算法5部分组成. 2.密码协议:也称为安全协议,是指以密码学为基础的消息交换的通信协议,目的是在网络环境中提供安全的服务. ...
- python3.6.3安装步骤,适用linux centos系统
step1: yum -y install gccyum install zlib zlib-devel step2: cd /usr/bin/ mv python python.bak step3: ...
- 《程序设计入门——C语言》翁恺老师 第一周编程练习记录
1 输出“Hello World”(5分) 题目内容: 请输出一行,内容为 Hello World 请注意大小写. 由于这一周只是简单地介绍了C程序的基本框架,还不能做很多事情,甚至还不能做数据的输入 ...
- Linux权限总结
第1章 课前小拓展 虚拟机打不开原因 问题: 该虚拟机似乎正在使用中. 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权.否则,请按“取消(C)”按钮以防损坏. 配置文件: E:\vm ...
- linux 虚拟机配置固定ip
参考这边博客: https://blog.csdn.net/u014466635/article/details/80284792 但是这个有个小问题,就是没有配置dns,导致连不上公网 /etc/s ...