自动化实践-全量Json对比在技改需求提效实践
1 背景
随着自动化测试左移实践深入,越来越多不同类型的需求开始用自动化测试左移来实践,在实践的过程中也有了新的提效诉求,比如技改类的服务拆分项目或者BC流量拆分的项目,在实践过程中,这类需求会期望不同染色环境在相同的配置条件下,拆分后的代码和基准release代码的接口响应response有全量对比结果才能更好达到需求验证点。
2 实践成果
在这种需要对接口返回response做全量json对比的背景下,商家域新的自动化平台新增了json全量对比的组件。在多个技改项目,比如服务拆分和BC流量拆分项目中这种比较大,花费人日比较多的项目测试中,应用了json全量对比验证。在实践过程中,比如原来要先写自动化,把响应结果挨个验证,或者在不同染色请求跟拆分前代码分别执行再对比结果。
在这种技改需求诉求下,全量json对比组件很好地满足了需要验证大量的服务拆分前接口和服务拆分后的接口返回json值全量对比。以商家服务拆分技改为例,技改跨几个迭代,需要回归大量的接口(目前该技改测试的接口已过千,还在跨迭代测试中)。测试过程利用全量json对比组件,不光测试一轮极大提高了测试效率,在二轮还可以用自动化回归提效。
3 实践过程
3.1 源组件:JSONCompareUtils
本次全量json对比引用的源组件是JSONCompareUtils,是Artemis框架提供的。JSONCompareUtils提供基于万行级Json的精确比对能力,这个能力基于一套嵌套降噪配置的递归算法实现。在配置合理的情况下,能快速进行较大Json串的比对。详情如下:
引入方式:
方法名:JSONCompare
参数:JSON expect, JSON actual, Properties properties
public static Map<String, String> JSONCompare(JSON expect, JSON actual, Properties properties) { Map<String, String> diffs = new HashMap<>(); if (null == expect && null == actual) { return diffs; } else if (expect instanceof JSONObject && actual instanceof JSONObject) { diffs.putAll(JSONObjectCompare((JSONObject) expect, (JSONObject) actual, "$", properties)); } else if (expect instanceof JSONArray && actual instanceof JSONArray) { diffs.putAll(JSONArrayCompare((JSONArray) expect, (JSONArray) actual, "$", properties)); } else { diffs.put("$", (expect + COMPARE_ARROW + actual) + "not the same instance type"); } if (!org.springframework.util.CollectionUtils.isEmpty(diffs)) { for (Map.Entry<String, String> entry : diffs.entrySet()) { logger.info("[key]" + entry.getKey() + "," + "[value]" + entry.getValue()); } } TrackingUtils.tracking(); return diffs;}
3.2 JSONCompareUtils组件改造
JSONCompareUtils组件改造后适应于目前效能平台适用的自动化平台组件。
改造后的组件:
改造后的组件名:21471: [JSON] 全量比对-两Json传入:对比接口提取返回与入参的json异同。
修改点:改成对比两个接口提取返回,提取字段取名json1、json2。
入参保留propeties:返回多个时候的排序字段,没有默认空,不排序。
举例:"propeties": "$.data.order=order_no",$.data.order为list[Object],以Object中order_no排序后,再对list做对比。
import json import requests def call(env_vars, g_vars, l_vars, sys_funcs, asserts, logger, **kwargs): param = sys_funcs.get_call_param() path = "http://******/artemis/component/interface- platform/compare/json" method = "POST" actual1 = l_vars.get("json1") actual2 = l_vars.get("json2") headers = { "Content-Type":"application/json; charset=utf8", } body = { "expect" : json.dumps(actual1,ensure_ascii=False), "actual" : json.dumps(actual2,ensure_ascii=False), "properties" : str(param["propeties"]) } logger.info("Artemis请求body:" + str(body)) try: resq = requests.post( path, data = json.dumps(body), headers = headers, timeout=8 ) res = json.loads(resq.text) logger.info("======================artemis组件结果======================") logger.info(res) asserts.assertTrue(res["success"], msg="调用artemis-interface异常") asserts.assertEqual(str(res["data"]), "{}", msg="存在不一致比对数据 :") except Exception as e: logger.info(f'执行JSON比对失败【{str(e)}】') raise e return res
3.3组件应用
步骤1: 提取接口返回json1、json2
步骤2:添加组件
步骤3:对比上面两个接口的提取的返回值
3.4 实践场景
3.4.1 实践一
提取接口返回全量标准被参照对比的标准json1,再提取新代码中期望跟标准json1对比的json2,添加全量json组件,对比json1和json2的值。
测试场景:服务拆分技改类需求中需要对不同服务两个或者多个接口返回response全量json结果对比的场景;
提取被参照对比全量json1见图一,对比全量json2见图二,组件执行结果见图三:
图一
图二
图三
3.4.2 实践二
返回json多次设置、多次对比数据。
测试场景:BC流量拆分前和拆分后的代码不同接口路由但是同一个业务功能,返回response全量json需要在不同染色多次对比结果的场景
json1、json2可进行多次设置、多次对比。
3.4.3 实践三
全量json对比不同环境返回数据。
测试场景:拆分前和拆分后的代码相同接口需要在相同配置不同染色环境下返回response全量json结果对比的场景
服务拆分的接口,不同染色环境对比返回的结果:举例如下:
3.4.4 实践四
全量json对比list结果返回顺序不一致的数据。
测试场景:拆分前和拆分后的代码相同接口返回response全量json需要先排序再对比结果的场景
Demo如下:
服务拆分的接口,请求是一个list数组,每次调用返回的list里面的顺序可能不一致,可利用组件的参数先排序再对比json返回结果,两个接口返回的json如下:
可用组件的"propeties": "$.data=userId"(或者"propeties": "$.data=merchantId")json里面的list先排序再对比,这样就规避了list返回顺序不一致的情况:
4 结论
在实际测试过程中,技改的需占比也不小,几乎每个迭代每个域都会有技改类的需求。本文为例,举了几个例子涉及提效需求点:
- 服务拆分技改类需求中需要对不同服务两个或者多个接口返回response全量json结果对比的场景;
- 拆分前和拆分后的代码相同接口需要在相同配置不同染色环境下返回response全量json结果对比的场景;
- 拆分前和拆分后的代码相同接口返回response全量json需要先排序再对比结果的场景;
- BC流量拆分前和拆分后的代码不同接口路由但是同一个业务功能,返回response全量json需要在不同染色多次对比结果的场景;
以上场景均能通过自动化+全量json对比组件的方式去提效测试,且在后续回归中直接用自动化覆盖回归,尤其在商家服务拆分跨好几个迭代涉及上千个接口的大的技改类需求中,达到明显的提效效果。
公司目前提供了很多现有的平台和小工具,不同类型的技改需求可以利用平台+小工具模式去实践应用,适合的场景下合理地应用,可以达到事半功倍的效果。
*文/mango
本文属得物技术原创,更多精彩文章请看:得物技术官网
未经得物技术许可严禁转载,否则依法追究法律责任!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Jupyter Notebook 遇上 NebulaGraph,可视化探索图数据库
在之前的《手把手教你用 NebulaGraph AI 全家桶跑图算法》中,除了介绍了 ngai 这个小工具之外,还提到了一件事有了 Jupyter Notebook 插件: https://github.com/wey-gu/ipython-ngql,可以更便捷地操作 NebulaGraph。 本文就手把手教你咋在 Jupyter Notebook 中,愉快地玩图数据库。 只要你仔细读完本文,一条 %ngql MATCH p=(n:player)->() RETURN p 命令就可以直接查询出数据,再接上 %ng_draw 就可以画出返回结果。 下面,进入今天的主菜——Jupyter Notebook 扩展:ipython-ngql。 其实,ipython-ngql 这个扩展断断续续地开发了两年,我一直没有开发完成。恰好之前有空,并完成了一直以来的心愿,把 ipython-ngql 重构并正式发布了。它除了完全适配 NebulaGrpah 3.x 所有查询之外,还支持了 Notebook 内的返回结果可视化。 在介绍 ipython-ngql 是什么之前,我先做个简单的 Jupy...
- 下一篇
Zadig vs. Jenkins 详细比对:时代的选择与开发者之选
01、Zadig vs. Jenkins:关于时代的选择 最近,我的合伙人 Grant 在官方公众号发布了一篇名为 《是时候和 Jenkins 说再见了》的文章,引起了社区的广泛关注和讨论。作为曾经最被广泛使用的持续构建交付工具,Jenkins 的江湖地位似乎被挑战了。评论中有一条被高度点赞顶起: 作为 Zadig 的创造者,我认为有必要与大家分享一份详细的比较文章。我的职业生涯伴随着工具、技术和基础设施的不断迭代,从十几年前的 TeamCity、Hudson,到 Jenkins、Travis、CircleCI 和 Drone,几乎每个产品和工具我个人都在企业环境下管理或者深度使用过,而 Jenkins 是我曾经非常推崇的选择。 回望 Zadig 来时的路,七年前 Zadig 她还是一个构想(Spock - 星际迷航的科学官及大副);五年前,她还是一个环境管理工具;三年前,她已经是一个好用的面向开发者的 CI/CD 平台;而今她在大规模客户的使用下,已然成为企业级一体化的云原生 DevOps 平台,通过广泛链接合作伙伴,为广义的企业开发者(包括产品、开发、测试、SRE、运维等不同职责的...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19