python接口测试非json的断言_荐在接口自动化测试中,如何利用Pytest + JSONPath 进行接口响应断言...

之前有一篇文章,介绍了如何使用JSONSchema对接口响应进行断言,主要的适用场景是对响应的数据结构进行校验,保证客户端收到的数据结构稳定和合法。今天,介绍使用JSONPath对接口响应的值进行断言方法。

上一篇文章《在接口自动化测试中,如何利用Pytest + JSON Schema 进行接口响应断言》中,介绍了JSON Schema校验接口响应的数据结构的方法。在实际的测试工作中,很多时候是需要对接口的响应数值进行校验的。这时候就不能利用JSON Schema进行校验了,需要借助JSONPath表达式从JSON中抽取数值,进行断言。

通过JSONPath表达式,使得从多层嵌套JSON数据中提取数据变得非常简单。

下面这段数据是从JsonPath的官网https://goessner.net/articles/JsonPath/上摘抄的,假定这是一个接口的response。

{ "store": {

"book": [

{ "category": "reference",

"author": "Nigel Rees",

"title": "Sayings of the Century",

"price": 8.95

},

{ "category": "fiction",

"author": "Evelyn Waugh",

"title": "Sword of Honour",

"price": 12.99

},

{ "category": "fiction",

"author": "Herman Melville",

"title": "Moby Dick",

"isbn": "0-553-21311-3",

"price": 8.99

},

{ "category": "fiction",

"author": "J. R. R. Tolkien",

"title": "The Lord of the Rings",

"isbn": "0-395-19395-8",

"price": 22.99

}

],

"bicycle": {

"color": "red",

"price": 19.95

}

},

"expensive": 10

}

从这个response中,提取所有商品的价格,放到一个列表中,如果使用JSONPath表达式,只需要一行代码:

$.store..price

代表JSON对象的根节点,代表JSON对象的根节点,代表JSON对象的根节点,代表JSON对象的根节点,.store表示根节点下面的store属性,$.store…price则表示根节点下面的store属性下面的所有price属性的值。两个点表示store下面递归查找所有的price属性,因此在这个例子中可以查到所有的book的price和bicycle的price。

一个更简单的办法是从根节点开始递归查找price:

$..price

如果不使用JSONPath,想要获得所有的商品价格,则要写一个循环来读取,可以看出,使用JSONPath从JSON中提取数据变得简单和高效。

接下来看看JSONPath中都有哪些表达式。

01 — JSONPath表达式

JSONPath通过表达式定位JSON中的数据,一共有15个表达式,通过它们的灵活组合,提取JSON中数据非常容易。我们把JSON对象中每一个key都叫做一个属性(property)。下表是所有的JSONPath表达式,及其含义。

以response这个JSON对象为例,通过上面这些表达式的组合来取得值:

表达式

取得的值

$.store.*

response的store属性下的所有对象,是个list,第1个元素book,是一个list,第2个元素是bicycle,是一个对象。

$.store.bicycle.color

response的store属性下bicycle属性的color属性的值,red

$.store..price、$..price

response中所有的price属性的值: [8.95, 8.99, 22.99, 19.95]

$.store.book[*] $..book[*]

response中所有的book对象,是个list

$…book[*].title

response中所有的book对象的title的list:[Sayings of the Century,Moby Dick,The Lord of the Rings]

$…book[0]

response中的第一本书,也是个list:[ { “category”:“reference”, “author”:“Nigel Rees”, “title”:“Sayings of the Century”, “price”:8.95 } ]

$…book[0].title

response中的第1本书的title:“Sayings of the Century”

$..book[0,1].title $..book[:2].title

response中的前2本书的title:[Sayings of the Century, Moby Dick]

$…book[::2].title

response中每一个取一本图书的title

$..book[-1:].title $..book[(@.length-1)].title

response最后1本书的title,是个list:[The Lord of the Rings]

$…book[?(@.author==‘J.R.R. Tolkien’)].title

过滤表达式,作者为’J.R.R. Tolkien’的book的书名

$…[?(@.isbn)]

过滤表达式,所有包含isbn这个属性的对象

$…[?(!@.isbn)]

过滤表达式,所有不包含isbn这个属性的对象

$…book[?(@.price < 10)]

价格低于10的书,是一个对象list

$..book[?(@.price > $.expensive)]

价格比$.expensive高的书,是个list

$..book[?(@.author =~ /.*Tolkien/i)]

作者的名字以Tolkien结尾的书,是个list,大小写敏感

$..book[?(@.category == 'fiction' || @.category == 'reference')]

category为fiction或者reference的书,是个list

通过上面的例子,可以看到还是挺简单的。

02 — 在断言中的应用

依然假定上面的JSON对象是某个接口的response反序列化得到的。接下来,看看在自动化测试中如何利用JSONPath表达式进行断言。

在Python语言中,使用JSONPath需要安装一个第三方库jsonpath。

pip install jsonpath

测试用例1:

验证response中包含’Nigel Rees’, ‘Evelyn Waugh’, ‘Herman Melville’, 'J. R. R. Tolkien’这四位作者的图书。

import jsonpath

def test_authors():

author_list = jsonpath.jsonpath(response, '$.store.book[*].author')

assert author_list == ['Nigel Rees', 'Evelyn Waugh', 'Herman Melville', 'J. R. R. Tolkien']

2. 测试用例2:

验证response中的商品价格包含8.95, 12.99, 8.99, 22.99, 19.95这5种。

def test_all_price():

store_price_list = jsonpath.jsonpath(response, '$.store..price')

# store_price_list = jsonpath.jsonpath(response, '$..price')

assert store_price_list == [8.95, 12.99, 8.99, 22.99, 19.95]

3.测试用例3:

验证response中的第3本图书的书名是Moby Dick。

def test_third_book_title():

book_3 = jsonpath.jsonpath(response, '$.store.book[2]')

assert book_3[0]['title'] == "Moby Dick"

4.测试用例4:

验证response中的最后一本图书的isbn是0-395-19395-8。

def test_last_book_isbn():

last_book_isbn = jsonpath.jsonpath(response, f'$.store.book[-1:].isbn')

# last_book_isbn = jsonpath.jsonpath(response, f'$.store.book[(@.length-1)].isbn')

assert last_book_isbn == "0-395-19395-8"

5.测试用例5:

验证repsonse中前两本书价格之和是8.95 + 12.99

def test_12_books_price():

book_12 = jsonpath.jsonpath(response, '$..book[0,1].price')

assert book_12[0] + book_12[1] == 8.95 + 12.99

6.测试用例6:

验证response中有两本书的价格小于10

def test_2books_cheap_than_10():

book_lg10 = jsonpath.jsonpath(response, '$..book[?(@.price<10)]')

assert len(book_lg10) <= 2

7.测试用例7:

验证response中具有color属性的商品,其color是red

def test_has_color():

colorful_goods = jsonpath.jsonpath(response, '$.store..[?(@.color)]')

assert "red" == colorful_goods[0]['color']

好了就举这些例子吧。更多的例子大家可以参考第一小节JSONPath表达式来尝试。

Python还有一个包叫jsonpath2,用法和jsonpath差不多。大家可以自行尝试,示例代码可以参考:

https://jsonpath2.readthedocs.io/en/latest/_modules/bookstore_test.html#TestBookStore

03 — 总结

本文介绍了JSONPath表达式语法,以及在自动化测试中的应用。使用JSONPath表达式提取JSON数据的数值,非常简介和易懂。推荐大家需要对JSON数据的准确性进行校验时,使用JSONPath表达式。

参考资料

https://goessner.net/articles/JsonPath/

https://www.cnblogs.com/angle6-liu/p/10580792.html

https://support.smartbear.com/alertsite/docs/monitors/api/endpoint/jsonpath.html

https://jsonpath2.readthedocs.io/en/latest/_modules/bookstore_test.html#TestBookStore

原文链接:https://blog.csdn.net/liuchunming033/article/details/106272542

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

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

相关文章

python3中异常处理_python中的五种异常处理机制介绍|python3教程|python入门|python教程...

https://www.xin3721.com/eschool/python.html从几年前开始学习编程直到现在&#xff0c;一直对程序中的异常处理怀有恐惧和排斥心理。之所以这样&#xff0c;是因为不了解。这次攻python&#xff0c;首先把自己最畏惧和最不熟悉的几块内容列出来&#xff0c;里面就有「异常处理…

java static 单例模式_Java 单例模式全面学习

介绍什么是单例模式&#xff1a;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点解决什么问题&#xff1a;省略创建对象所花费的时间&#xff0c;不需要频繁创建对象&#xff0c;减轻 GC 压力。单例模式有以下几种实现方式&#xff1a;懒汉式第一次使用的时候…

sql 没有调试 菜单_MySQL递归查询上下级菜单

正文在传统的后台管理系统里面经常会需要展示多级菜单关系&#xff0c;今天我们来学一下如何使用一条SQL语句展示多级菜单。现在我们有一张corpinfo单位表&#xff0c;里面有一个belong字段指向上级单位&#xff0c;首先来看一下现在表里有什么数据&#xff1a;SELECT uid,ubel…

java 桥 word_java导出word的6种方式(转发)

最近做的项目&#xff0c;需要将一些信息导出到word中。在网上找了好多解决方案&#xff0c;现在将这几天的总结分享一下。目前来看&#xff0c;java导出word大致有6种解决方案&#xff1a;1&#xff1a;Jacob是Java-COM Bridge的缩写&#xff0c;它在Java与微软的COM组件之间构…

python删除指定天数前的文件_python 删除指定时间间隔之前的文件实例

遍历指定文件夹下的文件&#xff0c;根据文件后缀名&#xff0c;获取指定类型的文件列表&#xff1b;根据文件列表里的文件路径&#xff0c;逐个获取文件属性里的“修改时间”&#xff0c;如果“修改时间”与“系统当前时间”差值大于某个值&#xff0c;则删除该文件。#!/usr/b…

jieba 词典 词频_在Hanlp词典和jieba词典中手动添加未登录词

在使用Hanlp词典或者jieba词典进行分词的时候&#xff0c;会出现分词不准的情况&#xff0c;原因是内置词典中并没有收录当前这个词&#xff0c;也就是我们所说的未登录词&#xff0c;只要把这个词加入到内置词典中就可以解决类似问题&#xff0c;如何操作呢&#xff0c;下面我…

android访问java服务器_Android_post访问java服务器端

//javaee工程访问地址String url "http://localhost:8080/TestAndroid";//把要请求的值封装到namevalupair的集合中NameValuePair nameValuePair1 new BasicNameValuePair("name","zhangsna");NameValuePair nameValuePair2 new BasicNameVal…

pythonweb啥意思_python-web-guide

Python Web 入坑指南____ _ _ __ __ _ ____ _ _| _ \ _ _| |_| |__ ___ _ __ \ \ / /__| |__ / ___|_ _(_) __| | ___| |_) | | | | __| _ \ / _ \| _ \ \ \ /\ / / _ \ _ \ | | _| | | | |/ _ |/ _ \| __/| |_| | |_| | | | (_) | | | | \ V V / __/ |_) | | |_| | |_| | | (_…

java范例_Java范例集锦(一)

范例1&#xff1a;不用其他变量实现两个变量通常在对变量互换时&#xff0c;将创建一个临时变量来共同完成互换&#xff0c;临时变量的互换增加了系统资源的消耗。如果需要交换的是两个整数类型的变量&#xff0c;则可以使用异或运算符(^)进行更高效的处理。实现代码如下&#…

python查找输出文字_Python基础练习,查询文本内容并输出;

1、编写可供用户查询的员工信息表&#xff1a;1).用户认证(输入用户名&#xff0c;密码)2).查询关键字&#xff1a;姓名3).显示ID&#xff0c;name&#xff0c;section&#xff0c;phone4).员工信息表内容如下&#xff1a;cat search_name.txt001wenlong IT12345678002xiaojun …

python列表索引超出范围 等于啥_python - IndexError:列表分配索引超出范围,Python

我正在尝试实现功能。它的工作方式应该是这样的&#xff1a;它需要两个列表。标记一些索引&#xff0c;最好居中。父母双方都切换标记索引。其他索引按顺序转到其父元素。如果该父元素中已经存在相同的元素&#xff0c;则它将映射并检查同一元素在其他父元素的位置并到达那里。…

python爬取汽车之家_python爬取 汽车之家(汽车授权经销商)

一&#xff1a;爬虫的目标&#xff1a;打开汽车之家的链接&#xff1a;https://www.autohome.com.cn/beijing/&#xff0c;出现如下页面我们的目标是点击找车&#xff0c;然后出现如下图我们要把图中的信息抓取到二&#xff1a;实现过程我们选择 宝马5系 然后点击找车注意宝马…

python跨目录调用_python 跨目录访问文件

1.同级、同目录的文件之间的访问有这样一个目录结构假如&#xff0c;in_A.py 这个文件想调用 hello_world.py 中的函数怎么办呢&#xff1f; --->>> import只需在 in_A.py 中 写入importhello_worldhello_world.functions()这样就可以访问啦&#xff0c;什么原理呢&a…

Java 调用 Caffe_解决 free(): invalid pointer: 0x00000000019ff700 运行时报错(caffe)(libtool使用)...

编译成功&#xff0c;运行时报错&#xff1a;在使用 pytorch or tensorflow or caffe 时&#xff0c;都可能存在这个问题&#xff1a;*** Error in xxx: free(): invalid pointer: 0x00000000020663b0 ***很可能是缺少libtcmalloc库解决方法1&#xff1a;apt-get安装libtcmallo…

unity 世界坐标间角度_Unity学习笔记—本地坐标转世界坐标

核心用到的方法就是transform.TransformPoint( )这个方法的返回值就是Vector3类型的世界坐标&#xff0c;transform就是相对的物体&#xff0c;括号里的就是相对这个transform的本地坐标&#xff0c;比方说我现在的位置吧&#xff0c;知道我相对于我的邻居的坐标:Pos1&#xff…

python访问序列元素的编号用什么括起来_python-重新编号数组中元素的有效方法...

我是python的新手,正在尝试实现一种遗传算法,但需要其中一项操作的代码方面的帮助.我是这样提出问题的&#xff1a;>每个人我都由一串M个整数表示> I中的每个元素e取值从0到N> 0到N之间的每个数字都必须在I中至少出现一次> e的值并不重要,只要每个唯一值元素采用相…

java 下载代码_实现文件下载的java代码

实现文件下载的java代码//这是实现下载类(servlet)&#xff0c;详细思路代码例如以下&#xff1a;//也可连接数据库package com.message;import javax.servlet.*;import javax.servlet.http.*;import java.io.*;import java.util.*;public class FileDownServlet extends HttpS…

webcomponents安装了没有用_Web Components 入门实例教程

来源 | http://www.ruanyifeng.com/blog/2019/08/web_components.html组件是前端的发展方向&#xff0c;现在流行的React和Vue都是组件框架。谷歌公司由于掌握了Chrome浏览器&#xff0c;一直在推动浏览器的原生组件&#xff0c;即Web组件API。部分第三方框架&#xff0c;原生组…

虹软java接摄像头_虹软人脸识别SDK(java+linux/window) 初试

虹软人脸识别全平台demo调用—快速上手之服务端Windows篇demo名称&#xff1a;ArcFace 2.2 Windows(86) Demo [C]一 环境配置&#xff1a;1) 安装VS2013环境安装包(vcredist_x86_vs2013.exe)2) 从官网(http://www.arcsoft.com.cn/ai/arcface.html)申请sdk&#xff0c;下载对应的…

python中re_Python中re(正则表达式)模块学习

今天学习了Python中有关正则表达式的知识。关于正则表达式的语法&#xff0c;不作过多解释&#xff0c;网上有许多学习的资料。这里主要介绍Python中常用的正则表达式处理函数。re.matchre.match 尝试从字符串的开始匹配一个模式&#xff0c;如&#xff1a;下面的例子匹配第一个…