提高接口自动化测试效率:使用 JMESPath 实现断言和数据提取!

news/2025/2/4 17:56:02/

前言

做接口自动化,断言是比不可少的。如何快速巧妙的提取断言数据就成了关键,当然也可以提高用例的编写效率。笔者在工作中接触到了JMESPath,那到底该如何使用呢?带着疑惑一起往下看。

JMESPath是啥?

JMESPath 是一种用于查询和转换 JSON 数据的简洁、强大的查询语言。它提供了一种灵活的方式来从复杂的 JSON 结构中提取所需的数据,并支持各种操作和函数,以满足不同的查询需求。

JMESPath如何使用?

在使用 JMESPath 查询 JSON 数据之前,我们需要安装 jmespath 库。安装命令如下:

pip install jmespath

简单路径表达式

假设我们有以下的 JSON 数据:

data = {"name": "Alice","age": 25,"email": "alice@example.com"
}

我们想要从中提取"name"属性的值。使用 JMESPath,我们可以编写以下代码:

import jmespath
​
expression = "name"
result = jmespath.search(expression, data)
​
print(result)  # 输出:Alice

这里,我们定义了一个路径表达式"name",然后使用jmespath.search()函数将该表达式应用于数据data上。结果会被存储在result变量中,并输出为"Alice"

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

嵌套属性访问

当 JSON 数据具有嵌套结构时,可以使用点号 . 连接多个属性名来表示深层的属性访问。考虑以下 JSON 数据:

data = {"person": {"name": "Alice","age": 25,"email": "alice@example.com"}
}

我们要提取"name"属性,可以使用以下路径表达式:

expression = "person.name"
result = jmespath.search(expression, data)
​
print(result)  # 输出:Alice

这里,我们将属性名 "person" 和 "name" 使用点号 . 连接起来,表示深层的属性访问。

复杂嵌套查询

假设我们有一个包含学生信息和他们的课程成绩的更复杂的 JSON 数据,如下所示:

data = {"students": [{"name": "Alice","courses": [{"name": "Math", "score": 95},{"name": "English", "score": 88}]},{"name": "Bob","courses": [{"name": "Math", "score": 75},{"name": "English", "score": 92}]}]
}

现在,假设我们想要获取每个学生的数学成绩。可以通过以下表达式实现:

expression = "students[].courses[?name == 'Math'].score"

再次执行查询并打印结果:

result = jmespath.search(expression, data)
print(result)

输出结果将是一个包含每个学生数学成绩的列表:

[[95], [75]]

列表索引

对于 JSON 中的列表属性,可以使用方括号 [index] 来指定索引位置来检索数据。假设我们有以下 JSON 数据:

data = {"fruits": ["apple", "banana", "cherry"]
}

我们想要提取第二个元素,即"banana"。可以使用以下路径表达式:

expression = "fruits[1]"
result = jmespath.search(expression, data)
​
print(result)  # 输出:banana

这里,我们使用方括号 [1] 来指定索引位置,表示提取第二个元素。

过滤器

JMESPath 提供了过滤器功能,使我们能够根据特定条件筛选出符合要求的数据。过滤器使用方括号 [?],后跟过滤条件。考虑以下 JSON 数据:

data = {"users": [{"name": "Alice", "age": 25},{"name": "Bob", "age": 30},{"name": "Charlie", "age": 28}]
}

我们想要提取年龄大于 25 岁的用户对象。可以使用以下路径表达式进行过滤:

expression = "users[?age > `25`]"
result = jmespath.search(expression, data)
​
print(result)

输出结果为:

[    {"name": "Bob", "age": 30},    {"name": "Charlie", "age": 28}]

这里,我们使用了过滤器 [?age > 25],表示只选择满足条件的用户对象。

合并操作

JMESPath 还支持合并操作符 [],用于将多个查询结果合并成一个列表。假设我们想要获取所有学生的所有课程名称。可以使用合并操作符 [] 来实现:

data = {"students": [{"name": "Alice","courses": [{"name": "Math", "score": 95},{"name": "English", "score": 88}]},{"name": "Bob","courses": [{"name": "Math", "score": 75},{"name": "English", "score": 92}]}]
}

获取所有学生的所有课程名称:

expression = "students[].courses[].name"
result = jmespath.search(expression, data)
print(result)

输出结果为:

['Math', 'English', 'Math', 'English']

排序和切片

JMESPath 还支持对查询结果进行排序和切片操作。假设我们想要按学生年龄进行降序排序。可以使用排序函数 sort() 和逆序函数 reverse() 来实现:

data = {"students": [{"name": "Alice", "age": 20},{"name": "Bob", "age": 22},{"name": "Charlie", "age": 21}]
}

得到按年龄降序排列的学生列表:

expression = "students | sort_by(@, &age) | reverse(@)"
​
result = jmespath.search(expression, data)
print(result) # [{'name': 'Bob', 'age': 22}, {'name': 'Charlie', 'age': 21}, {'name': 'Alice', 'age': 20}]

切片

data = {"fruits": ["apple", "banana", "cherry"]
}

利用切片获取第一个元素

import jmespath
​
data = {"fruits": ["apple", "banana", "cherry"]
}
expression = "fruits[0:1]"
result = jmespath.search(expression, data)
​
print(result) # ['apple']

管道

使用管道符号(|),将当前节点的结果传到管道符右侧继续投影。

data = {"students": [{"name": "Alice", "age": 20},{"name": "Bob", "age": 22},{"name": "Charlie", "age": 21}]
}

获取所有的姓名:

expression = "students[*].name"
result = jmespath.search(expression, data)
print(result) # ['Alice', 'Bob', 'Charlie']

如果在此基础上想要得到Bob这个值。我们尝试使用索引:

expression = "students[*].name[1]"
result = jmespath.search(expression, data)
print(result) # []

发现执行结果是一个空列表,这个时候怎么办呢?使用管道表达式, <expression> | <expression>

expression = "students[*].name | [1]"

内置函数

计算列表长度

data = {"students": [{"name": "Alice", "age": 20},{"name": "Bob", "age": 22},{"name": "Charlie", "age": 21}]
}
​
expression = "length(students)"  # 也可以这样写expression = "students | length(@)"
result = jmespath.search(expression, data)
print(result) # 3

length就是jmespath内置的函数。
当然还有一些其他常用的内置函数,比如:

  • starts_with(str, prefix): 检查字符串是否以指定前缀开头。
  • ends_with(str, suffix): 检查字符串是否以指定后缀结尾。
  • contains(str, substring): 检查字符串是否包含子字符串。
  • length(arr): 返回数组的长度。

最后

jmespath确实很强大,通过逐步学习和实践,可以更好地掌握 JMESPath 的功能和灵活性。

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
 

在这里插入图片描述


http://www.ppmy.cn/news/1120741.html

相关文章

3、Elasticsearch功能使用

第4章 功能使用 4.1 Java API 操作 随着 Elasticsearch 8.x 新版本的到来&#xff0c;Type 的概念被废除&#xff0c;为了适应这种数据结构的改 变&#xff0c;Elasticsearch 官方从 7.15 版本开始建议使用新的 Elasticsearch Java Client。 4.1.1 增加依赖关系 <propertie…

三相组合式过电压保护器试验

三相组合式过电压保护器试验 试验目的 三相组合式过电压保护器主要分为有带串联间隙过压保护器和无间隙过压保护器两大类&#xff0c;其试验项目内容要求分别使用高压工频交流和高压直流电源。 三相组合式过电压保护器试验&#xff0c;主要是为了及早发现设备内部绝缘受潮及…

根据条件关闭软件

使用下载工具时&#xff0c;经常出现磁盘空间已满&#xff0c;无法下载的情况。 使用shell写一个监控&#xff0c;每2分钟执行一次。判断当前磁盘的空间&#xff0c;低于2G时&#xff0c;关闭下载软件。 获取空间大小 ➜ ~ df -h …

数字IC验证高频面试问题整理—附答案(四)

好久没更新面试题目了&#xff0c;不少同学在后台催更&#xff0c;这不就来了~ 共150道验证高频面试题整理~含答案&#xff08;文末可领取全部题目&#xff09; Q1.illegal_bins和ignore_bins命中分别会怎么样&#xff1f;命中是否会计入覆盖率统计 illegal_bins 表示非法的…

数据结构(持续更新)

嗯,怎么说数据结构果然很玄妙。按照能不能存储多行元素大致分为两类。 不能存好几行的数据包括pair,int,float,double,char,struct; 能存好几行的:map,unordered_map,list,vector,set,string,array。 1. pair “pair” 是 C++ 标准库中的一个模板类,它用于存储…

09_CSS3多媒体查询

1 多媒体查询 1.1 媒体查询 媒体查询能在不同的条件下使用不同的样式&#xff0c;使页⾯在不同在终端设备下达到不同的渲染效果。 CSS 的 Media Query 媒体查询&#xff08;也称为媒介查询&#xff09;用来根据窗口宽度、屏幕比例和设备方向等差异来改变页面的显示方式。 使…

Failed to connect to bitbucket.org port 443 错误原因, 解决办法

最近使用SourceTree来访问bitbucket.org的代码托管Git, 当Pull或者Push发现操作失败: Failed to connect to bitbucket.org port 443 错误原因: 无法链接到网站地址, 可能是DNS解析IP地址错误, 或者网站维护, 大概率是被墙或者DNS解析错误. 解决办法: 如果您的浏览器能够访问b…

字符串 (3)--- KMP 算法的扩展

对于个长度为n的字符串s。定义函数z[i]表示s和s[i,n-1]&#xff08;即以 s[i] 开头的后缀&#xff09;的最长公共前缀&#xff08;LCP&#xff09;的长度。z被称为s的Z函数。特别地&#xff0c;z[0] 0。 如同大多数字符串主题所介绍的算法&#xff0c;其关键在于&#xff0c;…