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

前言

做接口自动化,断言是比不可少的。如何快速巧妙的提取断言数据就成了关键,当然也可以提高用例的编写效率。笔者在工作中接触到了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.hqwc.cn/news/115235.html

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

相关文章

LeetCode01

LeetCode01 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和 为目标值 target 的那两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你…

LabVIEW在运行时调整表控件列宽

LabVIEW在运行时调整表控件列宽 如何在LabIEW中运行时调整表控件的列宽大小&#xff1f; 在VI运行时&#xff0c;有两种不同的方法可以更改表中列的宽度。首先&#xff0c;可以使用鼠标手动更改它们;其次&#xff0c;可以从框图中以编程方式更改它们。 手动更改列宽 只有在…

Rsync学习笔记2

Rsync&#xff1a; 增量操作&#xff1a; 1&#xff09; server01服务文件变动。 [rootserver03 tp5shop]# rsync -av /usr/local/nginx/html/tp5shop root192.168.17.109:/usr/local/nginx/html/ sending incremental file listsent 88,134 bytes received 496 bytes 177,…

GDB的TUI模式(文本界面)

2023年9月22日&#xff0c;周五晚上 今晚在看GDB的官方文档时&#xff0c;发现GDB居然有文本界面模式 TUI (Debugging with GDB) (sourceware.org) GDB开启TUI的条件 GDB的文本界面的开启条件是&#xff1a;操作系统有适当版本的curses库 The TUI mode is supported only on…

【Stm32】【Lin通信协议】Lin通信点亮灯实验

Lin通信点亮灯实验 通过STM32的串口发送数据&#xff0c;然后通过串口转换模块将数据转换成LIN&#xff08;Local Interconnect Network&#xff09;协议&#xff0c;最终控制点亮灯。需要工程和入门资料的可以私信我&#xff0c;看到了马上回。 入门书本推荐&#xff1a; 一…

Quartz 建表语句SQL文件

SQL文件在jar里面&#xff0c;github下载 https://github.com/quartz-scheduler/quartz/releases/tag/v2.3.2 解压&#xff0c;sql文件路径&#xff1a;quartz-core\src\main\resources\org\quartz\impl\jdbcjobstore tables_mysql_innodb.sql # # In your Quartz propertie…

Python150题day09

③多条件分支 使用input函数接收用户的输入数据&#xff0c;如果用户输入python&#xff0c;则输出90&#xff0c;如果用户输入java.输出95&#xff0c;如果用户输入php&#xff0c;输出85&#xff0c;其他输入&#xff0c;程序输出0 解答&#xff1a; if...elif...else val…

七天学会C语言-第三天(循环语句)

1. 用 while 语句循环做数学运算&#xff1a; 使用while语句&#xff0c;您可以创建一个循环&#xff0c;它会重复执行一段代码&#xff0c;直到指定的条件不再满足。 例 1&#xff1a; 求 246100。 #include <stdio.h>int main() {int n 1, sum 0, a 2;while (n &…

xp 系统 安装 python 2.7 ide pip

1 下载python http://www.python.org/ftp/python/ python-2.7.2.msi 安装完需要设置环境变量 2 下载 setuptools setuptools-0.6c11.win32-py2.7.exe https://pypi.tuna.tsinghua.edu.cn/simple/setuptools/ 3 下载 pip &#xff0c;python 2.7 最高支持 pip 20.3.4 https:…

外包干了2个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

基于SpringBoot+Vue的MOBA类游戏攻略分享平台

1 简介 MOBA类游戏攻略分享平台&#xff0c;为用户随时随地查看游戏攻略信息提供了便捷的方法&#xff0c;更重要的是大大的简化了管理员管理MOBA类游戏攻略信息的方式方法&#xff0c;更提供了其他想要了解MOBA类游戏攻略信息及运作情况以及挑选方便快捷的可靠渠道。相比于传…

Redis应用(8)——Redis的项目应用:结合SpringBoot如何在Redis里面存对象 RedisUtil工具类的封装 遇到的问题

前言 Redis作为一款优秀的开源、高效的内存数据库&#xff0c;在各种项目中都能见到其身影&#xff0c;熟练使用Redis是程序员必备的技能之一。本系列博客结合应用场景&#xff0c;阐述Redis从安装到使用的&#xff0c;从入门到进阶的相关内容。 本篇博客介绍在Spring项目中&…