Python 使用 JsonPath 完成接口自动化测试中参数关联和数据验证

背景:

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

痛点:

  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']

小练习:

import json
import jsonpath

jsonStr = '''
        {   
    "lemon": {
        "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
}'''


def get_value_byjsonpath(jsonpathstr, expression):
    """
    通过jsonpath处理json对象获取对应得值
    :param jsonpathstr:json格式字符串
    :param expression:表达式
    :return: 返回列表
    """
    # 将jsonpathstr转化为json对象
    try:
        jsonpathstr = json.loads(jsonpathstr)
    except:
        raise
    else:
        result = jsonpath.jsonpath(jsonpathstr, expression)
        return result

#获取所有老师得名称
print(get_value_byjsonpath(jsonStr,'$.lemon.teachers[*].name'))

  

本文转载自:http://www.lemfix.com/topics/63

posted @ 2019-03-14 18:10  上官夏洛特  阅读(258)  评论(0)    收藏  举报