随着迭代的更替,业务数据数据越来越庞大、复杂,日常测试中,JSON数据存在每次id都变化、数组顺序变化、坐标发生变化、json中包转义json等现象,现有的JSON对比工具无法解决所有问题。业务线需要做对比,必须对数据进行特殊处理,未来数据结构发生变化,维护成本高。
基于此,我们决定开发一款通用的,能够支持个性化对比需求,拓展性好的JSON对比工具,来解决业务线日常测试中的JSON对比的难题。
基于以上背景,我们对工具进行如下设计:
入参模块:
对比规则:对于复杂的对比需求,我们必然需要定义标准化的规则,来简化使用过程。我们同时也考虑到,一旦有一定的使用量,我们需要有规则库来管理业务数据的对比规则,便于用户的使用与维护。
对比能力:需满足特殊数据的个性化对比以及良好的拓展性。
对比结果:JSON对比工具可以作为独立的工具供用户使用,也可以作为一个工具类提供给开发人员。所以我们考虑到返回结果的多样性以满足不同用户的需求。
在定义对比规则之前,我们需要先完成JSON对比功能的设计,再基于功能设计制定标准的规则模板。下文将依次阐述JSON对比功能的实现、规则的管理、对比结果。
目前市面上存在非常多的JSON对比工具,最基础的JSON对比能力不需要我们再重复造轮子,我们需要实现的是对特殊数据的个性化对比以及良好的拓展性来应对数据的变化。
首先整理我们具体的对比需求。
需求 |
---|
JSON存在每次计算都发生变化的字段,如timestamp、id,对比时需要忽略这些字段 |
JSONArray里的元素的顺序会发生变化,需要不按顺序进行对比 |
数值类型的数据可能每次计算存在一些误差,如坐标值,需要能容忍一些数值误差进行对比 |
有些字段的值是一个String类型的转义JSON,需要反转义后视为JSON进行对比 |
市面上的JSON对比实现方式大同小异,大体分为:格式化后逐行文本化对比、对JSON对象进行遍历对比。文本化对比无法满足我们的需求,因此我们需要在遍历对比的基础上进行改造。
在遍历JSON的过程中,每遍历到一个节点,我们就能得到这个节点的Path,并且这个Path是唯一的。结合上图的基础模型,我们可以在每次判断值类型之前,判断当前的JSON Path对应的值是否需要进行特殊的对比,再交给对应的特殊对比模块进行对比,这样就能满足支持个性化对比和拓展性好的需求了。
我们选取了JSON这一大家熟知的文件格式来作为规则的格式,规则中包含JSON Path和对应的匹配器,JSON Path必须支持正则匹配、通配匹配,使我们更方便地使用个性化对比功能。
GIT自带在线编辑、diff、回滚、历史记录等功能,方便维护使用,没有任何开发成本。
通过raw url可直接读取规则内容。
如果需要在别的地方也能同步获取规则库的规则,可以利用git webhook。如下图使用Jenkins+git webhook进行数据库的同步,这样任何后端服务想要访问JSON对比规则库,可以直接访问更便于访问的数据库。
简单易读的对比结果,我们仅记录对比失败的结果,每条记录包含:JSON Path、失败原因、实际值、预期值
3.3.2 提供给开发者的对比结果
标明结果成功与否,对比结果分类,给开发者提供更多信息
到此我们已经实现了我们想要的JSON对比功能了。在后续的实际的使用过程中,我们发现了很多可以优化的地方。
分别支持顺序和乱序的JSONArray不同长度的对比
乱序的对比的采用的是遍历的对比算法,时间复杂度为O(n^2)。当对比的数组每个元素都不一致,会达到最坏情况,即遍历n^2次。如果该JSONArray的节点数非常多,或者下面还有乱序对比的子数组节点,对比耗时将非常高。于是我们考虑到,对于每个数组元素都是同一结构的JSONObject来说,一般能够找到unique key来标志每个元素,如以下结构的JSON。
那么,我们可以新增一个指定JSONArray中的unique key的匹配器让用户主动优化算法,新增一个自动寻找unique key的方法自动优化算法。这样,只要能够找到unique key,程序的时间复杂度就变成了O(n),大大提高了性能。程序结构大致如下图:
在线对比工具供普通用户使用,提供对比规则辅助编写工具,以树形结构展示对比结果、高亮错误
对比规则辅助编写工具,帮助用户快速编写规则,并联动规则库,便于使用与管理
打包上传,供开发者使用,无需详述
这篇分享,讲述了我们开发这款工具的目的、设计并开发的思路、以及后续对工具的管理和优化。这个过程中,我们几乎零成本地完成了规则库的开发,低成本地满足了我们的对比需求。
设计工具时首先要明确当下需求和未来需求,最好能考虑如何应对未来的变化。尽可能不重复造轮子,利用好现有的资源,考虑如何快速完成工具。希望大家看了之后能够对开发测试工具有清晰的思路。
后话:在设计之初,我们浏览了很多开源项目,希望为我们的实现找到一些参考和思路。最终,我们在开源项目http://jsonassert.skyscreamer.org/cookbook.html的基础上完成了该工具。
以上是本篇全部内容,如果你有任何想法或建议,欢迎在我们公众号聊天对话框中发送消息。
推荐阅读