接口测试 04 -- Jsonpath断言、接口关联处理

2024-01-22 13:20

本文主要是介绍接口测试 04 -- Jsonpath断言、接口关联处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. JsonPath基本介绍

1.1 JsonPath简介

JsonPath是一种用于在JSON数据中定位和提取特定数据的表达式语言。它类似于XPath用于XML的定位和提取,可以帮助我们灵活地从复杂的JSON结构中获取所需的数据。

 1.2 JsonPath的特点

● JsonPath可处理的报文类型为字典类型

● 通过JsonPath成功获得的内容,会以list的形式进行返回,也就意味着你的 JsonPath是可以有一个值或者多个值同时存在的。

● 如果要基于JsonPath来处理json数据,就一定要去同步处理list

● JsonPath定义中,如果表达式出现错误,则会返回False(布尔类型的值)

● JsonPath要么返回False,要么返回list

1.3 JsonPath安装

pip install jsonpath    # 安装命令
pip show jsonpath       # 安装效验

1.4 JsonPath实际运行场景

对应做软件测试来说:

1. 主要能够通过这个方式提取数据
2. 业务场景: 断言 、接口关联

常规的报文也避免不了比较复杂的情况,如下所示包含了一个人员的信息,包括姓名、年龄、邮箱、地址、爱好、教育背景和参与的项目。
它展示了JSON数据的嵌套结构和多种数据类型的使用,那么我们应该如何进行解决呢?
{
"name": "Alice",
"age": 25,
"email": "alice@example.com",
"address": {
"street": "456 Elm Street",
"city": "Los Angeles",
"country": "USA"
},
"hobbies": ["reading", "traveling", "cooking"],
"education": [
{
"degree": "Bachelor's",
"major": "Computer Science",
"university": "ABC University",
"year": 2018
},
{
"degree": "Master's",
"major": "Business Administration",
"university": "XYZ University",
"year": 2020
}
],
"projects": [
{
"name": "Project A",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"contributors": ["John", "Sarah", "Mike"],
"completed": "true"
},
{
"name": "Project B",
"description": "Nulla vel sagittis elit. Vivamus auctor massa in lacinia pellentesque.",
"contributors": ["Alice", "David"],
"completed": "false"
}
],
"is_active": "true"
}

举一个栗子:提取上面这段代码中education里的年份值

更多提取信息,语法格式,先下面“JsonPath基本格式规范-示例参考

从上图可以看出:返回的数据类型是列表

1.5 JsonPath基本格式规范

以下是一些JsonPath的常用语法和示例:

附:jsonpath在线解析器 http://www.atoolbox.net/Tool.php?Id=792

$ 根节点,也是所有JsonPath表达式的开始
. 表示获取子节点
.. 表示获取所有符合条件的内容
* 代表所有的元素节点
[index] 表示迭代器的标示(可以用于处理下标等情况)
[,] 表示多个结果的选择
[start:end] 指定范围内的元素
?(@.property == value) 表示过滤操作 # 比较运算符
@ 表示当前节点
示例参考:
① 基本语法
$ :根节点,也是所有JsonPath表达式的开始
. :当前节点
.. :递归下级节点
② 属性操作
$.property :选择指定属性
$['property'] :选择指定属性,属性名带有特殊字符时使用

③ 数组操作(含头不含尾)

$.array[index] :选择指定索引处的元素
$.array[start:end] :选择指定范围内的元素

 ④ 过滤器(比较运算符都可以用)

$.array[?(@.property == value)] :根据条件过滤数组元素
$.array[?(@.property > value)] :根据条件过滤数组元素

⑤ 路径组合

$.parent.child :选择父节点下的子节点
$.parent[*].child :选择父节点下所有子节点的某个属性

1.6 JsonPath断言实例

一个登陆接口的正向用例:

断言 :提取响应数据和期望数据进行对比

import jsonpath
import requests
import json# 完整的请求url
url = "http://xxxx域名/index.php?s=/api/user/login" # 公共参数
pulic_data = {"application": "app", "application_client_type": "weixin"}
# 登陆接口请求参数
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}json_data = json.dumps(data)  # 将请求参数转为json格式# 指定请求头的参数的数据格式为json
header = {'Content-Type':'application/json;charset=utf-8'}# 发送请求    
res = requests.post(url,params=pulic_data,headers=header,data=json_data)print(res.json())exData = "登录成功"   # 期望结果# 实际结果:最后记得加索引,不然会报错
SjData = jsonpath.jsonpath(res.json(),"$.msg")[0]  
# 断言 期望结果结果等于实际结果,并格式化输出期望结果、实际结果
assert exData == SjData,"期望结果是:{0},实际结果是:{1}".format(exData,SjData)

所有工具中的断言都一样,如果断言成功,则不会显示断言信息,也不会报错

如果断言失败,则报错信息中显示断言信息

2. 接口关联

2.1 接口关联意义

接口关联是在进行接口测试时,将一个接口的返回结果中的某些数据提取出来,然后作为后续接口请求的参数或者验证的依据。通过接口关联,可以实现接口间的数据传递和依赖关系的建立。

2.2 接口关联类型

接口关联通常分为两种类型:请求关联和响应关联。
1. 请求关联
提取关键参数 :在一个接口的请求中,某些参数的值是由之前接口的响应结果提供的。需要提取出这些关键参数,并将其作为后续接口的请求参数。
例如,一个接口的请求中需要使用到某个用户的登录令牌(token),可以通过在登录接口的响应结果中提取出令牌(token),然后在后续接口的请求中使用。
----------->>>
2. 响应关联
验证关键数据 :在一个接口的响应结果中,某些数据是需要验证的,可以将这些数据提取出来,并进行断言或者其他验证操作。
例如,一个接口的响应结果中包含了某个订单的状态信息,可以将该状态信息提取出来,然后进行断言,验证订单是否处于正确的状态。

2.3 加入购物车案例

这里还是基于上个案例的登录接口(某电商平台):

1. 首先登录成功,提取token值。

2. 通过提取的token,将商品加入购物车。

使用josnpath提取token

第一步:将打印信息换成text文件,方便接下来去调试

import json
import requests
import jsonpathurl = "http://xxxx域名/index.php?s=/api/user/login" 
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}header = {'Content-Type': 'application/json; charset=utf-8'}
json_data = json.dumps(data)# --------------------发送接口请求---------------------------
res = requests.post(url, params=pulic_data, headers=header,data=json_data) # 正确的演示# --------------------获取响应数据---------------------------
print(res.text)    # 改成获取text文本内容# --------------------获取数据进行断言处理---------------------------
exData = "登录成功"
SjData = jsonpath.jsonpath(res.json(),"$.msg")[0]
assert exData == SjData, "期望结构是:{0},实际结果是:{1}".format(exData, SjData)

第二步:将上一步的代码运行,复制控制台输出的响应内容,全部黏贴到json在线工具中,美化一下格式:JSON在线解析及格式化验证 - JSON.cn

第三步:复制黏贴美化后的响应内容,到josnpath在线工具中,进行调试

ps:如果代码能力强的,可以跳过这两步,直接写josnpath提取token的代码

josnpath提取响应信息中的token,有上面两种写法,第二种更简单

第四步:去完善代码

import json
import requests
import jsonpathurl = "http://xxxx域名/index.php?s=/api/user/login" 
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}header = {'Content-Type': 'application/json; charset=utf-8'}
json_data = json.dumps(data)# --------------------发送接口请求---------------------------
res = requests.post(url, params=pulic_data, headers=header,data=json_data) # 正确的演示# --------------------获取响应数据---------------------------
print("响应信息:",res.text)    # 改成获取text文本内容# --------------------获取数据进行断言处理---------------------------
exData = "登录成功"
SjData = jsonpath.jsonpath(res.json(),"$.msg")[0]
assert exData == SjData, "期望结构是:{0},实际结果是:{1}".format(exData, SjData)# --------------------获提取token值---------------------------
token =jsonpath.jsonpath(res.json(),"$..token")[0]
print("提取出来的token值:",token)

加入购物车

完整代码:

import json
import requests
import jsonpathurl = "http://xxxx域名/index.php?s=/api/user/login" 
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}header = {'Content-Type': 'application/json; charset=utf-8'}
json_data = json.dumps(data)# --------------------发送接口请求---------------------------
res = requests.post(url, params=pulic_data, headers=header,data=json_data) # 正确的演示# --------------------获取响应数据---------------------------
print("响应信息:",res.text)    # 改成获取text文本内容# --------------------获取数据进行断言处理---------------------------
exData = "登录成功"
SjData = jsonpath.jsonpath(res.json(),"$.msg")[0]
assert exData == SjData, "期望结构是:{0},实际结果是:{1}".format(exData, SjData)# --------------------获提取token值---------------------------
token =jsonpath.jsonpath(res.json(),"$..token")[0]
print("提取出来的token值:",token)# --------------------加入购物车---------------------------
# 加入购物车请求参数
data = {"goods_id":"10", # 商品id"spec": "",      # 商品规格,无规格"stock": 1       # 加入数量
}# 公共参数
params = {"application": "app","application_client_type": "weixin","token": token
}
res = requests.post(url="http://xxxx域名/index.php?s=api/cart/save", params=params, json=data)
print(res.json())

打开web页面:也显示加入成功

拿到对应的项目,一定要梳理出来对应的业务流程及它对应接口之间的关联关系
任何项目:都需要理解需求、业务流程

=====================================================================

基于这个思路:还可以梳理出不同的测试场景
1. 浏览商品--加入购物车 (有规格/无规格) --从购物车去提交订单
a.选择商品[一般对应列表都是会有 (购物车)列表接口,都会有id)
b.选择对应的地址
c.选择支付方式)--订单支付

---------------->>>
2. 浏览商品--加入购物车--从购物车去提交订单--取消订单

---------------->>>
3. 浏览商品--提交订单
a.从数据库找商品表 (找到商品名称字段)
b.从页面上获取 (id,一般会在页面对应的url中)

=====================================================================

可以看出,接口测试,与功能测试的思路、场景都是一样的

再换一个有商品规格的商品,加入购物车

import json
import requests
import jsonpathurl = "http://xxxx域名/index.php?s=/api/user/login" 
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}header = {'Content-Type': 'application/json; charset=utf-8'}
json_data = json.dumps(data)# --------------------发送接口请求---------------------------
res = requests.post(url, params=pulic_data, headers=header,data=json_data) # 正确的演示# --------------------获取响应数据---------------------------
print("响应信息:",res.text)    # 改成获取text文本内容# --------------------获取数据进行断言处理---------------------------
exData = "登录成功"
SjData = jsonpath.jsonpath(res.json(),"$.msg")[0]
assert exData == SjData, "期望结构是:{0},实际结果是:{1}".format(exData, SjData)# --------------------获提取token值---------------------------
token =jsonpath.jsonpath(res.json(),"$..token")[0]
print("提取出来的token值:",token)# --------------------加入购物车---------------------------
# 加入购物车请求参数,有规格值
data = {"goods_id": "11","spec": [{"type": "尺寸","value": "L"}],"stock": "10"}# 公共参数
params = {"application": "app","application_client_type": "weixin","token": token
}
res = requests.post(url="http://xxxx域名/index.php?s=api/cart/save", params=params, json=data)
print(res.json())

再加一个查看购物车接口、并提取购物车列表Id:

import json
import requests
import jsonpathurl = "http://xxxx域名/index.php?s=/api/user/login" 
pulic_data = {"application": "app", "application_client_type": "weixin"}
data = {"accounts": "hailey", "pwd": "hailey123", "type": "username"}header = {'Content-Type': 'application/json; charset=utf-8'}
json_data = json.dumps(data)# --------------------发送接口请求---------------------------
res = requests.post(url, params=pulic_data, headers=header,data=json_data) # 正确的演示# --------------------获取响应数据---------------------------
print("响应信息:",res.text)    # 改成获取text文本内容# --------------------获取数据进行断言处理---------------------------
exData = "登录成功"
SjData = jsonpath.jsonpath(res.json(),"$.msg")[0]
assert exData == SjData, "期望结构是:{0},实际结果是:{1}".format(exData, SjData)# --------------------获提取token值---------------------------
token =jsonpath.jsonpath(res.json(),"$..token")[0]
print("提取出来的token值:",token)# --------------------加入购物车---------------------------
# 加入购物车请求参数,有规格值
data = {"goods_id": "11","spec": [{"type": "尺寸","value": "L"}],"stock": "10"}# 公共参数
params = {"application": "app","application_client_type": "weixin","token": token
}
res = requests.post(url="http://xxxx域名/index.php?s=api/cart/save", params=params, json=data)
print(res.json())# --------------------购物车列表---------------------------
# 公共参数,查看购物车没有请求参数
params = {"application": "app","application_client_type": "weixin","token": token
}
res = requests.get(url="http://xxx域名/index.php?s=api/cart/index", params=params)
print(res.json())
cardid  =jsonpath.jsonpath(res.json(),"$..id")[0] # 推荐的用法
print("提取出来的商品id:>>",cardid)

总结

思路

web自动化、api接口自动化,本质上都是模拟用户操作,所以手工测试有哪些步骤、自动化同样也有哪些步骤。

列表页面:商品列表、购物列表,任何列表都有增删改查,所以都会有对应的接口,接口关联依赖上一个接口的数据,一般都会有一个 (列表)唯一值 id。

这篇关于接口测试 04 -- Jsonpath断言、接口关联处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/633102

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

Thymeleaf:生成静态文件及异常处理java.lang.NoClassDefFoundError: ognl/PropertyAccessor

我们需要引入包: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>sp

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果: 解密后的数据就是正常数据: 后端:使用的是spring-cloud框架,在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version></dependency> 编写一个AES加密

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚