自动化实践-全量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());}

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 ereturn 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 结论

在实际测试过程中,技改的需占比也不小,几乎每个迭代每个域都会有技改类的需求。本文为例,举了几个例子涉及提效需求点:

1.服务拆分技改类需求中需要对不同服务两个或者多个接口返回response全量json结果对比的场景;

2.拆分前和拆分后的代码相同接口需要在相同配置不同染色环境下返回response全量json结果对比的场景;

3.拆分前和拆分后的代码相同接口返回response全量json需要先排序再对比结果的场景;

4.BC流量拆分前和拆分后的代码不同接口路由但是同一个业务功能,返回response全量json需要在不同染色多次对比结果的场景;

以上场景均能通过自动化+全量json对比组件的方式去提效测试,且在后续回归中直接用自动化覆盖回归,尤其在商家服务拆分跨好几个迭代涉及上千个接口的大的技改类需求中,达到明显的提效效果。

公司目前提供了很多现有的平台和小工具,不同类型的技改需求可以利用平台+小工具模式去实践应用,适合的场景下合理地应用,可以达到事半功倍的效果。

*文/mango

本文属得物技术原创,更多精彩文章请看:得物技术官网

未经得物技术许可严禁转载,否则依法追究法律责任!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/81359.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

检验代码生成器完成版

写维护页面重复逻辑写烦了&#xff0c;连页面的增、删、改、查、弹窗等代码都不行手写了&#xff0c;为此做成代码生成器成型版1.0.干到10点。。。 代码&#xff1a; Class Demo.CodeGener Extends %RegisteredObject {/// 生成操作表相关的代码&#xff0c;包括M、C#调用代码…

【go-zero】docker镜像直接部署go-zero的API与RPC服务 如何实现注册发现?docker network 实现 go-zero 注册发现

一、场景&问题 使用docker直接部署go-zero微服务会发现API无法找到RPC服务 1、API无法发现RPC服务 用docker直接部署 我们会发现API无法注册发现RPC服务 原因是我们缺少了docker的network网桥 2、系统内查看 RPC服务运行正常API服务启动,通过docker logs 查看日志还是未…

迭代器模式(C++)

定义 提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c;而又不暴露(稳定)该对象的内部表示。 应用场景 在软件构建过程中&#xff0c;集合对象内部结构常常变化各异。但对于这些集合对象&#xff0c;我们希望在不暴露其内部结构的同时&#xff0c;可以让外部客户代…

BpBinder与PPBinder调用过程——Android开发Binder IPC通信技术

在Android系统中&#xff0c;进程间通信&#xff08;IPC&#xff09;是一个非常重要的话题。Android系统通过Binder IPC机制实现进程间通信&#xff0c;而Binder IPC通信技术则是Android系统中最为重要的进程间通信技术之一。本文将介绍Binder IPC通信技术的原理&#xff0c;并…

JMeter处理接口签名之BeanShell实现MD5加密

项目A需要给项目B提供一个接口&#xff0c;这个接口加密了&#xff0c;现在需要测试这个接口&#xff0c;需要怎么编写脚本呢&#xff1f;实现接口签名的方式有两种&#xff1a;BeanShell实现MD5加密和函数助手实现MD5加密&#xff0c;之前已经分享过了函数助手实现MD5加密&…

[Linux]计算机软硬体系结构

[Linux]计算机软硬体系结构 文章目录 [Linux]计算机软硬体系结构冯诺依曼体系结构冯诺依曼体系结构的组成冯诺依曼体系结构中各部件的功能对存储器(内存)的理解对数据流的理解 了解操作系统操作系统的概念管理的概念管理的本质管理的精髓“先描述&#xff0c;再组织”计算机软硬…

SpringCloud之微服务API网关Gateway介绍

文章目录 1 微服务API网关Gateway1.1 网关1.1.1 简介1.1.2 相比于Zuul 1.2 Spring Cloud Gateway介绍1.3 Gateway特性1.4 Gateway工作流程1.5 Gateway核心概念1.5.1 路由1.5.1.1 定义1.4.1.2 动态路由 1.4.2 断言1.4.2.1 默认断言1.4.2.2 自定义Predicate 1.4.3 过滤器1.4.3.1 …

Llama 2 云端部署与API调用【AWS SageMaker】

Meta 刚刚发布了 Llama 2 大模型。如果你和我们一样&#xff0c;你一定会迫不及待地想要亲自动手并用它来构建。 推荐&#xff1a;用 NSDT设计器 快速搭建可编程3D场景。 使用任何类型的 LLM 进行构建的第一步是将其托管在某处并通过 API 使用它。 然后你的开发人员可以轻松地将…

决策树和随机森林对比

1.用accuracy来对比 # -*-coding:utf-8-*-""" accuracy来对比决策树和随机森林 """ from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_wine#(178, 13…

【Spring】使用注解存储Bean对象

目录 一、配置扫描路径&#xff08;使用注解的方式存对象的前提&#xff09; 二、使用类注解存储Bean对象 1、使用五大类注解存储Bean对象 2、为什么要这么多的类注解&#xff1f; 2.1、五大类注解之间的关系 3、获取Bean对象时的默认命名规则 三、使用方法注解来存储…

2023年新手如何学剪辑视频 想学视频剪辑如何入门

随着短视频、vlog等媒体形式的兴起&#xff0c;视频剪辑已经成为了热门技能。甚至有人说&#xff0c;不会修图可以&#xff0c;但不能不会剪视频。实际上&#xff0c;随着各种智能软件的发展&#xff0c;视频剪辑已经变得越来越简单。接下来&#xff0c;一起来看看新手如何学剪…

以指标驱动,保险、零售、制造企业开启精益敏捷运营的新范式

近日&#xff0c;以“释放数智生产力”为主题的 Kyligence 用户大会在上海前滩香格里拉大酒店成功举行。大会包含上午的主论坛和下午的 4 场平行论坛&#xff0c;并举办了闭门会议、Open Day 等活动。来自金融、零售、制造、医药等行业的客户及合作伙伴带来了超过 23 场主题演讲…

VAE、 EM、KL散度

文章目录 VAEVAE额外的损失函数 EMKL散度 VAE 左图相当于变量x&#xff0c;右图相当于z 假如在AE中&#xff0c;一张满月的图片作为输入&#xff0c;模型得到的输出是一张满月的图片&#xff1b;一张弦月的图片作为输入&#xff0c;模型得到的是一张弦月的图片。当从满月的code…

瞅一眼nginx

目录 &#x1f9ac;什么是nginx? &#x1f9ac;nginx配置官方yum源&#xff1a; &#x1f9ac;nginx优点 &#x1f9ac;nginx 缺点 &#x1f9ac;查看nginx默认模块 &#x1f40c;nginx新版本的配置文件&#xff1a; &#x1f40c;nginx目录索引 &#x1f40c;nginx状态…

网络编程(JavaEE初阶系列10)

目录 前言&#xff1a; 1.网络编程的基础 1.1为什么需要网络编程 1.2什么是网络编程 1.3网络编程中的基本概念 1.3.1发送端和接收端 1.3.2请求和响应 1.3.3客户端和服务端 2.Socket套接字 2.1概念 2.2分类 3.UDP数据报套接字编程 3.1DataGramSocket API 3.2Datagr…

【游戏客户端】制作你玩我猜Like玩法

【游戏客户端】制作你玩我猜Like玩法 大家好&#xff0c;我是Lampard猿奋~~ “你画我猜”相信大家都不陌生&#xff0c;当初这款小游戏可谓茶余饭后必玩之选&#xff0c;风头一时无二。今天要和大家分享如何实现一个你玩我猜Like的玩法。 我们可以简单的把需求拆成两个个部分&…

python实现对图油画、卡通、梦幻、草图、水彩效果

本篇博客将介绍如何使用wxPython模块和OpenCV库来实现对图像进行灰度化、二值化、伽马校正、色彩空间转换和图像反转这5种效果的合并程序。程序可以通过wxPython提供的GUI界面来选择图片路径和效果类型&#xff0c;程序会将处理后的图像保存到指定路径并打开。 步骤一&#xf…

2021年12月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题(共25题,每题2分,共50分) 第1题 昨天的温度是5摄氏度,今天降温7摄氏度,今天的温度是多少摄氏度? A:12 B:7 C:2 D:-2 正确的答案是 D:-2。 解析: 根据题目描述,昨天的温度是 5 摄氏度,今天降温了 7 摄氏度。降温意味着温度变低,所以今天的温度…

k8s之Pod控制器

目录 一、Pod控制器及其功用二、pod控制器的多种类型2.1 pod容器中的有状态和无状态的区别 三、Deployment 控制器四、SatefulSet 控制器4.1 StatefulSet由以下几个部分组成4.2 为什么要有headless&#xff1f;4.3 为什么要有volumeClaimTemplate&#xff1f;4.4 滚动更新4.5 扩…

解决MAC M1处理器运行Android protoc时出现的错误

Protobuf是Google开发的一种新的结构化数据存储格式&#xff0c;一般用于结构化数据的序列化&#xff0c;也就是我们常说的数据序列化。这个序列化协议非常轻量级和高效&#xff0c;并且是跨平台的。目前&#xff0c;它支持多种主流语言&#xff0c;比传统的XML、JSON等方法更具…