实例分享:用JsonPath来做接口测试

在这里插入图片描述

我们在做接口测试的时候,返回的json结构比较复杂,特别是嵌套比较多的时候,就不太好处理。有没有比较简便的方法呢?

肯定是有的,python里面有jsonpath,jsonpath-rw等模块来快速处理json结构。这两个模块差不多,讲讲其中的jsonpath吧。

JsonPath模块

1、JsonPath介绍

用来解析多层嵌套的json数据;JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, PHP 和 Java。

2、JsonPath 对于 JSON 来说,相当于 XPath 对于 XML。

安装方法:pip install jsonpath

官方文档:http://goessner.net/articles/JsonPath

3、JsonPath与XPath语法对比:

Json结构清晰,可读性高,复杂度低,非常容易匹配,下表中对应了XPath的用法。

背景:

1、接口自动化测试实现简单、成本较低、收益较高,越来越受到企业重视。

2、restful风格的api设计大行其道。

3、json成为主流的轻量级数据交换格式。

痛点:

1、接口关联也称为关联参数。在应用业务接口中,完成一个业务功能时,有时候一个接口可能不满足业务的整个流程逻辑,需要多个接口配合使用。简单的案例如:B接口的成功调用依赖于A接口,需要在A接口的响应数据(response)中拿到需要的字段,在调用B接口的时候,传递给B接口作为B接口请求参数,拿到后续响应的响应数据。接口关联通常可以使用正则表达式去提取需要的数据,但对于json这种简洁、清晰层次结构、轻量级的数据交互格式。使用正则未免有点杀鸡用牛刀的感觉(是的,因为我不擅长写正则表达式),我们需要更加简单、直接的提取json数据的方式。

2、数据验证,这里的数据验证指的是对响应结果进行数据的校验,接口自动化测试中,对于简单的响应结果(json),可以直接和期望结果进行比对,判断是否完全相等即可。如 json {“status”:1,“msg”:“登录成功”}

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

3、解决方案

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

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

也可以使用中括号[]的形式,如shell $[‘store’][‘book’][0][‘title’]

例如:

  d={
          "error_code": 0,
          "stu_info": [
                  {
                          "id": 2059,
                          "name": "小红",
                          "sex": "女",
                          "age": 21,
                          "addr": "上海浦东大道32号",
                          "grade": "天蝎座",
                          "phone": "18378309272",
                          "gold": 10896,
                          "info":{
                              "card":434345432,
                              "bank_name":'中国银行'
                          }
                  },
                  {
                          "id": 2067,
                          "name": "小亮",
                          "sex": "男",
                          "age": 28,
                          "addr": "上海南京西路1088号",
                          "grade": "天蝎座",
                          "phone": "12345678915",
                          "gold": 100
                  }
          ]
  }
  res= d["stu_info"][1]['name'] #取某个学生姓名的原始方法:通过查找字典中的key以及list方法中的下标索引
  print(res) #输出结果是:小亮
  import jsonpath
  res1=jsonpath.jsonpath(d,'$..name') #嵌套n层也能取到所有学生姓名信息,$表示最外层的{}..表示模糊匹配
  print(res1) #输出结果是list:['小红', '小亮']
  res2= jsonpath.jsonpath(d,'$..bank_name')
  print(res2) #输出结果是list:['中国银行']
  res3=jsonpath.jsonpath(d,'$..name123') #当传入不存在的key(name),返回False
  print(res3) #输出结果是:False

再来一个例子:

  dict = { "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
      }
    }
  }
  import jsonpath
  res1=jsonpath.jsonpath(dict,'$..author')
  print(res1)

ok, 我们可以尝试来做接口:

对36氪的快讯接口解析,只要知道最终要取的字段名就好,不用写完整的字典取值,可以省不少事:

  import requests
  import json
  import jsonpath
  header = {
          'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
                        '(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
      }
  url = 'https://36kr.com/api/newsflash?&per_page=20'
  response = requests.get(url,
                          headers=header,
                          timeout=5
                          )
  dict = json.loads(response.text)
  title=jsonpath.jsonpath(dict,"$..title]")
  des=jsonpath.jsonpath(dict, '$..description')
  publish=jsonpath.jsonpath(dict, '$..published_at')
  for i in range(20):
      print(title[i]," ",des[i], " ", publish[i])

在这里插入图片描述

最后: 可以在公众号:伤心的辣条 ! 自行领取一份216页软件测试工程师面试宝典文档资料【免费的】。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

学习技术千万不要孤军奋战,最好是能抱团取暖,相互成就一起成长,群众效应的效果是非常强大的,大家一起学习,一起打卡,会更有学习动力,也更能坚持下去。你可以加入我们的测试技术交流扣扣群:914172719(里面有各种软件测试资源和技术讨论)

喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!


好文推荐

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…

什么样的人适合从事软件测试工作?

那个准点下班的人,比我先升职了…

测试岗反复跳槽,跳着跳着就跳没了…

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值