全网最详细,python接口自动化测试JsonPath接口关联数据验证(实战)


前言

接口自动化测试实现简单、成本较低、收益较高,越来越受到企业重视;
restful风格的api设计大行其道;
json成为主流的轻量级数据交换格式;

python接口自动化测试:https://www.bilibili.com/video/BV16G411x76E/

接口关联

接口关联也称为关联参数。在应用业务接口中,完成一个业务功能时,有时候一个接口可能不满足业务的整个流程逻辑,需要多个接口配合使用,简单的案例如:B接口的成功调用依赖于A接口,需要在A接口的响应数据(response)中拿到需要的字段,在调用B接口的时候,传递给B接口作为B接口请求参数,拿到后续响应的响应数据。

接口关联通常可以使用正则表达式去提取需要的数据,但对于json这种简洁、清晰层次结构、轻量级的数据交互格式,使用正则未免有点杀鸡用牛刀的感觉(是的,因为我不擅长写正则表达式),我们需要更加简单、直接的提取json数据的方式。

数据验证

这里的数据验证指的是对响应结果进行数据的校验
接口自动化测试中,对于简单的响应结果(json),可以直接和期望结果进行比对,判断是否完全相等即可。如

{
    
    "status":1,"msg":"登录成功"}

对于格式较复杂,尤其部分数据存在不确定性、会根据实际情况变化的响应结果,简单的判断是否完全相等(断言)通常会失败。如:

{
    
    "status":1,"code":"10001","data":[{
    
    "id":1,"investId":"1","createTime":"2018-04-27 12:24:01","terms":"1","unfinishedInterest":"1.0","unfinishedPrincipal":"0","repaymentDate":"2018-05-27 12:24:01","actualRepaymentDate":null,"status":"0"},{
    
    "id":2,"investId":"1","createTime":"2018-04-27 12:24:01","terms":"2","unfinishedInterest":"1.0","unfinishedPrincipal":"0","repaymentDate":"2018-06-27 12:24:01","actualRepaymentDate":null,"status":"0"},{
    
    "id":3,"investId":"1","createTime":"2018-04-27 12:24:01","terms":"3","unfinishedInterest":"1.0","unfinishedPrincipal":"100.00","repaymentDate":"2018-07-27 12:24:01","actualRepaymentDate":null,"status":"0"}],"msg":"获取信息成功"}

上面的json结构嵌套了很多信息,完整的匹配几乎不可能成功。比如其中的createTime信息,根据执行接口测试用例的时间每次都不一样。同时这个时间是响应结果中较为次要的信息,在进行接口自动化测试时,是可以选择被忽略的。

我们需要某种简单的方法,能够从json中提取出我们真正关注的信息(通常也被称为关键信息)。如提取出status的值为1,data数组中每个对象的investId都为1,data中第三个对象的unfinishedPrincipal值为100.00,只要这三个关键信息校验通过,我们就认为响应结果没有问题

解决方案
JsonPath可以完美解决上面的痛点。通过JsonPath可以从多层嵌套的Json中解析出所需要的值。

JsonPath

JsonPath参照XPath解析xml的方式来解析Json
JsonPath用符号$表示最外层对象,类似于Xpath中的根元素
JsonPath可以通过点语法来检索数据,如:

$.store.book[0].title 

也可以使用中括号[]的形式,如

$['store']['book'][0]['title']

运算符(Operators)

运算符 说明
$ 根元素
@ 当前元素
* 通配符,可以表示任何元素
递归搜索
. 子节点(元素)
[‘’ (, ‘’)] 一个或者多个子节点
[ (, )] 一个或者多个数组下标
[start:end] 数组片段,区间为[start,end)
[?()] 过滤器表达式,其中表达式结果必须是boolean类型,如可以是比较表达式或者逻辑表达式

JsonPath案例

{
    
    
    "lemon": {
    
    
        "teachers": [
            {
    
    
                "id": "101",
                "name": "张三",
                "addr": "湖南长沙",
                "age": 25
            },
             {
    
    
                "id": "102",
                "name": "李四",
                "age": 28
            },
            {
    
    
                "id": "103",
                "name": "王五",
                "addr": "广东深圳",
                "age": 16
            },
             {
    
    
                "id": "104",
                "name": "AAA",
                "addr": "广东广州",
                "age": 29
            }
        ],
        "salesmans": [
            {
    
    
                "id": "105",
                "name": "BBB",
                "age": 17
            },
             {
    
    
                "id": "106",
                "name": "CCC",
                "age": 27
            }
        ]
    },
 "avg": 25
}

使用jsonpath模块

# 1:导入相关模块
import json
import jsonpath

# 2: 准备json字符串
jsonStr = '''
          {
    "lemon": {
        "teachers": [
            {
                "id": "101",
                "name": "张三",
                "addr": "湖南长沙",
                "age": 25
            },
             {
                "id": "102",
                "name": "李四",
                "age": 28
            },
            {
                "id": "103",
                "name": "王五",
                "addr": "广东深圳",
                "age": 16
            },
             {
                "id": "104",
                "name": "AAA",
                "addr": "广东广州",
                "age": 29
            }
        ],
        "salesmans": [
            {
                "id": "105",
                "name": "BBB",
                "age": 17
            },
             {
                "id": "106",
                "name": "CCC",
                "age": 27
            }
        ]
    },
 "avg": 25
}
'''

# 3:加载json字符串为json对象
json_obj = json.loads(jsonStr)

# 4:使用jsonpath模块的jsonpath方法提取信息
# eg1: 提取所有包含addr属性的信息,结果为list类型
results = jsonpath.jsonpath(json_obj,"$..teachers[?(@.addr)]")  
print(results)

# eg2:提取所有年龄小于20岁的name,结果为list类型
results2 = jsonpath.jsonpath(json_obj,"$.lemon.teachers[?(@.age < 20)].name")  
print(results2)

使用jsonpath_rw

# 1:导入相关模块
import json
from jsonpath_rw import jsonpath, parse

# 2: 准备json字符串
jsonStr = '''
  # 同上(略)
'''

# 3:加载为json对象
json_obj = json.loads(jsonStr)

# 4:采用parse创建jsonpath对象(该案例是得到所有的name)
jsonpath_expr = parse('$.lemon.teachers[*].name')

# 5:通过jsonPath检索json后返回匹配的数据,类型是DatumInContext的list
datumInContexts = jsonpath_expr.find(json_obj)
# 采用列表推导式检索出所有匹配的值
values = [datum.value for datum in datumInContexts]
print(values)


# 案例2:提取索引为4的的name
jsonpath_expr = parse('$.lemon.teachers[3].name')
datumInContexts = jsonpath_expr.find(json_obj)
print(datumInContexts)
values = [datum.value for datum in datumInContexts]
print(values)
下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

失败是什么?没有什么,只是更走近成功一步;成功是什么?就是走过了所有通向失败的路,只剩下一条路,那就是成功的路。

快乐总和宽厚的人相伴,财富总与诚信的人相伴,智慧总与高尚的人相伴,魅力总与幽默的人相伴,健康总与豁达的人相伴。

经验环境和遗传造就了你的面目,无论是好是坏,你都得耕耘自己的园地;无论是好是坏,你都得弹起生命中的琴弦。

猜你喜欢

转载自blog.csdn.net/x2waiwai/article/details/129693512