• jsonpath完成接口关联处理


    1. 接口关联
      • 也称为关联参数。在应用业务接口中,完成一个业务功能时,有时候一个接口可能不满足业务的整个流程逻辑,需要多个接口配合使用,简单的案例如:B接口的成功调用依赖于A接口,需要在A接口的响应数据(response)中拿到需要的字段,在调用B接口的时候,传递给B接口作为B接口请求参数,拿到后续响应的响应数据。
      • 接口关联通常可以使用正则表达式去提取需要的数据,但对于json这种简洁、清晰层次结构、轻量级的数据交互格式,使用正则未免有点杀鸡用牛刀的感觉(是的,因为我不擅长写正则表达式),我们需要更加简单、直接的提取json数据的方式。
    2. 数据验证
      • 这里的数据验证指的是对响应结果进行数据的校验
      • 接口自动化测试中,对于简单的响应结果(json),可以直接和期望结果进行比对,判断是否完全相等即可。如 json {"status":1,"msg":"登录成功"}
      • 对于格式较复杂,尤其部分数据存在不确定性、会根据实际情况变化的响应结果,简单的判断是否完全相等(断言)通常会失败。如: json {"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可以通过点语法来检索数据,如: shell $.store.book[0].title
    • 也可以使用中括号[]的形式,如 shell $['store']['book'][0]['title']

    运算符(Operators)

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

    JsonPath案例

    json

    {
        "xdf_company": {
            "teachers": [
                {
                    "id": "101",
                    "name": "老王",
                    "addr": "北京海淀",
                    "age": 25
                },
                 {
                    "id": "102",
                    "name": "老李",
                    "age": 28
                },
                {
                    "id": "103",
                    "name": "老刘",
                    "addr": "山东济南",
                    "age": 16
                },
                 {
                    "id": "104",
                    "name": "老史",
                    "addr": "山东青岛",
                    "age": 29
                }
            ],
            "salesmans": [
                {
                    "id": "105",
                    "name": "老高",
                    "age": 17
                },
                 {
                    "id": "106",
                    "name": "老范",
                    "age": 27
                }
            ]
        },
     "avg": 25
    }

    JsonPath例子及说明

    JsonPath路径说明
    $.xdf_company.teachers[*].name 获取所有老师的的名称
    $..name 获取所有人的名称
    $.xdf_company.* 所有的老师和销售
    $.xdf_company..age 所有人的年龄
    $..age 所有人的年龄
    $.xdf_company.teachers[*].age 所有老师的年龄
    $.xdf_company.teachers[3] 索引为3(第4个)老师的信息
    $..teachers[3] 索引为3(第4个)老师的信息
    $.xdf_company.teachers[-2] 倒数第2个老师的信息
    $..teachers[-2] 倒数第2个老师的信息
    $..teachers[1,2] 第2到第3个老师的信息
    $..teachers[:2] 索引0(包含)到索引2(不包含)的老师信息
    $..teachers[1:3] 索引1(包含)到索引3(不包含)的老师信息
    $..teachers[-2:] 最后的两个老师的信息
    $..teachers[2:] 索引2开始的所有老师信息
    $..teachers[?(@.addr)] 所有包含地址的老师信息(jsonpath_rw不支持)
    $.xdf_company.teachers[?(@.age < 20)] 所有年龄小于20的年龄信息(jsonpath_rw不支持)

    一:使用jsonpath

    安装jsonpath模块

    pip install jsonpath==0.75
    

    解析

    # 1:导入相关模块
    import json
    import jsonpath
    
    # 2: 准备json字符串
    jsonStr = '''
              {
        "xdf_company": {
            "teachers": [
                {
                    "id": "101",
                    "name": "老王",
                    "addr": "北京海淀",
                    "age": 25
                },
                 {
                    "id": "102",
                    "name": "老李",
                    "age": 28
                },
                {
                    "id": "103",
                    "name": "老刘",
                    "addr": "山东济南",
                    "age": 16
                },
                 {
                    "id": "104",
                    "name": "老史",
                    "addr": "山东青岛",
                    "age": 29
                }
            ],
            "salesmans": [
                {
                    "id": "105",
                    "name": "老高",
                    "age": 17
                },
                 {
                    "id": "106",
                    "name": "老范",
                    "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)
      # 输出结果:[{'id': '101', 'name': '老王', 'addr': '北京海淀', 'age': 25}, {'id': '103', 'name': '老刘', 'addr': '山东济南', 'age': 16}, {'id': '104', 'name': '老史', 'addr': '山东青岛', 'age': 29}]
    # eg2:提取所有年龄小于20岁的老师的name,结果为list类型
      results2 = jsonpath.jsonpath(json_obj,"$.xdf_company.teachers[?(@.age < 20)].name")
      print(results2)   # 输出结果为:['老刘']

    二:使用jsonpath_rw

    安装jsonpath_rw模块

    pip install 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('$.xdf_company.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('$.xdf_company.teachers[3].name')
    datumInContexts = jsonpath_expr.find(json_obj) print(datumInContexts) values = [datum.value for datum in datumInContexts] print(values) # 结果为:['老刘']
    {
        "xdf_company": {
            "teachers": [
                {
                    "id": "101",
                    "name": "老王",
                    "addr": "北京海淀",
                    "age": 25
                },
                 {
                    "id": "102",
                    "name": "老李",
                    "age": 28
                },
                {
                    "id": "103",
                    "name": "老刘",
                    "addr": "山东济南",
                    "age": 16
                },
                 {
                    "id": "104",
                    "name": "老史",
                    "addr": "山东青岛",
                    "age": 29
                }
            ],
            "salesmans": [
                {
                    "id": "105",
                    "name": "老高",
                    "age": 17
                },
                 {
                    "id": "106",
                    "name": "老范",
                    "age": 27
                }
            ]
        },
     "avg": 25
    }
    xdf_company
  • 相关阅读:
    display的几种常用取值
    css五种定位方式介绍
    单行文字超过某个宽度时,显示省略号
    点击鼠标右键弹出错误提示:CrashHandler initialization error
    基于jquery 的find()函数和children()函数的区别
    跨域问题,前端主动向后台发送cookie
    Boolean()值为false的五个特殊值
    如何把select默认的小三角替换成自己的图片
    如何将网页的title前面的图标替换成自己的图标
    C#阿里云 移动推送 接入
  • 原文地址:https://www.cnblogs.com/fcc-123/p/13170895.html
Copyright © 2020-2023  润新知