接口自动化——多层嵌套响应断言

一、多层嵌套响应

1.1、多层嵌套结构

// - 层级多。
// - 嵌套关系复杂。
{
  "errcode": 0,
  "errmsg": "ok",
  "userid": "zhangsan",
  "name": "张三",
  "department": [1, 2],
  "order": [1, 2],
  "position": "后台工程师",
  "mobile": "13800000000",
  "gender": "1",
  "email": "zhangsan@gzdev.com",
  "biz_mail": "zhangsan@qyycs2.wecom.work",
  "is_leader_in_dept": [1, 0],
  "direct_leader": ["lisi", "wangwu"],
  "avatar": "http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0",
  "thumb_avatar": "http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/100",
  "telephone": "020-123456",
  "alias": "jackzhang",
  "address": "广州市海珠区新港中路",
  "open_userid": "xxxxxx",
  "main_department": 1,
  "extattr": {
    "attrs": [
      {
        "type": 0,
        "name": "文本名称",
        "text": {
          "value": "文本"
        }
      },
      {
        "type": 1,
        "name": "网页名称",
        "web": {
          "url": "http://www.test.com",
          "title": "标题"
        }
      }
    ]
  },
  "status": 1,
  "qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=xxx",
  "external_position": "产品经理",
  "external_profile": {
    "external_corp_name": "企业简称",
    "wechat_channels": {
      "nickname": "视频号名称",
      "status": 1
    },
    "external_attr": [
      {
        "type": 0,
        "name": "文本名称",
        "text": {
          "value": "文本"
        }
      },
      {
        "type": 1,
        "name": "网页名称",
        "web": {
          "url": "http://www.test.com",
          "title": "标题"
        }
      },
      {
        "type": 2,
        "name": "测试app",
        "miniprogram": {
          "appid": "wx8bd80126147dFAKE",
          "pagepath": "/index",
          "title": "my miniprogram"
        }
      }
    ]
  }
}

1.2、响应提取

场景 方式
提取 errcode 对应的值 res["errcode"]
提取 title 对应的值 res["extattr"]["external_profile"]["external_attr"][1]["web"]["title"]
提取 type 为 0 的 name 编码实现
提取 attrs 下的所有的 name 编码实现

二、JSONPath 语法

2.1、jsonpath简介

在JSON数据中定位和提取特定信息的查询语言
JSONpath使用路径表达式从JSON中提取数据,语法类似XPATH定位
相比于传统的提取方式更加灵活,并支持定制化

2.2、JSONPath 与传统定位对比

场景 对应实现 JSONPath 实现
提取 errcode 对应的值 res["errcode"] $.errcode
提取 title 对应的值 res["extattr"]["external_profile"]["external_attr"][1]["web"]["title"] $..title
提取 type 为 0 的 name 编码实现 $..external_attr[?(@.type==0)].name
提取 attrs 下的所有的 name 编码实现 $..attrs..name

三、JSONPath 使用

3.1、JSONPath语法

符合 描述
$ 查询根节点对象,用于表示一个JSON数据,可以说是数组或对象
@ 过滤器(filter predicate),处理当前结点对象
* 通配符
. 获取子结点
递归搜索,筛选所有符合条件的结点
?() 过滤器表达式,筛选操作
[start:end] 数组片段,左闭右开。
[A]或[A,B] 迭代器下标,表示一个或多个数组下标

3.2、JSONPath练习

//JSON对象
{
  "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
}
  • 获取所有书籍的作者:$..book..author
  • 获取所有作者:$..author
  • 获取 store 下面的所有内容:$..store
  • 获取所有的价格:$..price
  • 获取第三本书:$..book[2]
  • 获取所有包含 isbn 的书籍:$..book[?(@.isbn)]
  • 获取所有价格小于 10 的书:$..book[?(@.price<10)]
  • 获取所有书籍的数量:$..book.length

四、JSON代码示例

  • 在python中,如果找到则返回列表,如果未找到则返回Fasle
class TestJsonPath:
    def test_case01(self):
        url = "https://httpbin.ceshiren.com/post"
        res = requests.post(url, verify=False)
        json_obj = res.json()
        # print(json_obj)
        sw = jsonpath.jsonpath(json_obj, "$..Sw")
        print(sw)

五、JSONPath扩展

JSONPath Description
$ the root object/element
@ the current object/element
. or child operator
recursive descent. JSONPath borrows this syntax from E4X.
* wildcard. All objects/elements regardless their names.
subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator.
[,] Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set.
[start:end:step] array slice operator borrowed from ES4.
?() applies a filter (script) expression.
() script expression, using the underlying script engine.