pytest + yaml 框架 -43.支持自定义函数提取返回结果

发布时间 2023-06-26 22:52:45作者: 上海-悠悠

前言

在 yaml 用例中提取返回结果,可以支持以下三种表达式

  • jmespath 取值语法: body.keyname.keyname
  • jsonpath 语法: $..keyname
  • re 正则语法

以上三种表达式可以满足 99% 的测试场景需求了,但是有些特殊的需求通过表达式无法取到,为了满足另外1%的需求,可以自定义函数取值。
此功能在v1.3.6版本实现

场景描述

有个小伙伴给我提了个需求:如果返回的结果中有某个值就断言,没有就不断言

示例:如下返回结果,当data中name的值为"yoyo"的时候,断言它的邮箱值"283340479@qq.com",如果结果中没有name的值为"yoyo"就不断言

res = {
    "code": 0,
    "msg": "成功success!",
    "data": [
       {
           "age": 20,
           "create_time": "2019-09-15", 
           "id": 1, 
           "mail": "283340479@qq.com", 
           "name": "yoyo", 
           "sex": "M"
       },
       {
           "age": 21, 
           "create_time": "2019-09-16", 
           "id": 2,
           "mail": "123445@qq.com", 
           "name": "yoyo111", 
           "sex": "M"
       }
    ]
}

代码示例

先自定义函数取值,传一个 reponse (接口返回对象)

conftest.py 内容如下:

from pytest_yaml_yoyo import  my_builtins


def fun_x(response):

    res = response.json()
    for item in res['data']:
        if item.get("name") == "yoyo":
            return item.get("mail") == "283340479@qq.com"
    return True


my_builtins.fun_x = fun_x

yaml 用例中内容, 校验地方可以引用函数${fun_x(response)}, response 参数是接口返回对象。
test_rep.yml

test_rep:
  name: z
  request:
    url: /api/test/demo
    method: get

  validate:
    - eq: ["hello", "hello"]
    - eq: ["${fun_x(response)}", true]

执行用例

pytest test_rep.yml

运行结果:

2023-06-26 22:45:08 [INFO]: 取值表达式: fun_x(response), 取值结果:True <class 'bool'>
2023-06-26 22:45:08 [INFO]: validate 校验内容-> [{'eq': ['hello', 'hello']}, {'eq': [True, True]}]
2023-06-26 22:45:08 [INFO]: validate 校验结果-> eq: [hello, hello]
2023-06-26 22:45:08 [INFO]: validate 校验结果-> eq: [True, True]
2023-06-26 22:45:08 [INFO]: export 导出全局变量:{}