0
点赞
收藏
分享

微信扫一扫

pytest + yaml 框架 -6.hooks 钩子功能实现

前言

在发送请求的时候,我们希望在发送请求参数前,带上签名的值,或者返回的内容需要二次处理,解密后返回。
此功能我们可以用 hooks 钩子来实现
pip 安装插件

pip install pytest-yaml-yoyo

hooks 功能在v1.0.4版本上实现

response 钩子功能

requests 库只支持一个 response 的钩子,即在响应返回时可以捎带执行我们自定义的某些方法。
可以用于打印一些信息,做一些响应检查或想响应对象中添加额外的信息

# 作者-上海悠悠tang/
import requests
url = 'https://httpbin.org/get'


def response_status(resopnse, *args, **kwargs):
print('url', resopnse.url)
resopnse.status = 'PASS' if resopnse.status_code < 400 else 'FAIL'


res = requests.get(url, hooks={'response': response_status})
print(res.status)

以上是基于requests 库的钩子功能实现的基本方式

yaml 用例中添加response 钩子

在yaml 文件中添加response 钩子功能,跟上面代码方式差不多, 有2种方式

  • 1.写到config 全局配置,每个请求都会带上hooks
  • 2.写到单个请求的request 下,仅单个请求会带上hooks功能

先看单个请求的response 钩子
test_hook1.yml

# 作者-上海悠悠 
config:
name: post示例
teststeps:
-
name: post
request:
method: POST
url: http://httpbin.org/post
json:
username: test
password: "123456"
hooks:
response: ['hook_response']
extract:
url: body.url
validate:
- eq: [status_code, 200]
- eq: [headers.Server, gunicorn/19.9.0]
- eq: [$.code, 0]
-
name: post
request:
method: POST
url: http://httpbin.org/post
json:
username: test
password: "123456"
extract:
url: body.url
validate:
- eq: [status_code, 200]
- eq: [headers.Server, gunicorn/19.9.0]
- eq: [$.code, 0]

在conftest.py 中注册钩子函数

# 作者-上海悠悠 

def hook_response(response, *args, **kwargs):
# print(response.text) 原始数据
print("执行response hook 函数内容....")
class NewResponse:
text = '{"code": 0, "data": {"token": "yo yo"}}' # response.text解密
history = response.history
headers = response.headers
cookies = response.cookies
status_code = response.status_code
raw = response.raw
is_redirect = response.is_redirect
content = b'{"code": 0, "data": {"token": "yo yo"}}' # response.text解密
elapsed = response.elapsed

@staticmethod
def json():
# 拿到原始的response.json() 后解码
return {"code": 0, "data": {"token": "yo yo"}}

return NewResponse

my_builtins.hook_response = hook_response

由于上面用例只在第一个请求中使用了hooks功能,所以第二个请求的断言​​- eq: [$.code, 0]​​ 会失败

钩子方法调用语法

  • 1.层级是在request 下
  • 2.hooks 关键字对应的是一个字典 {"response": []}
  • 3.response 的值可以是单个函数名称,也可以是多个​​func1, func2​​,或者是一个list类型[func1, func2]
  • 4.response 的值必须是一个可以调用的函数,此函数需在conftest 中注册绑定到​​my_builtins​​ 模块
  • 5.调用的函数第一个参数是​​response​​, 可以重写response内容(如需要对返回结果解密),也可以不用重写

request:
method: POST
url: http://httpbin.org/post
hooks:
response: ['hook_response']

config 全局使用

在config 中配置全局hooks功能,格式如下

config:
name: post示例
hooks:
response: ['hook_response']

test_hook2.yml完整示例

config:
name: post示例
hooks:
response: ['hook_response']
teststeps:
-
name: post
request:
method: POST
url: http://httpbin.org/post
json:
username: test
password: "123456"
hooks:
response: ['hook_response']
extract:
url: body.url
validate:
- eq: [status_code, 200]
- eq: [headers.Server, gunicorn/19.9.0]
- eq: [$.code, 0]
-
name: post
request:
method: POST
url: http://httpbin.org/post
json:
username: test
password: "123456"
extract:
url: body.url
validate:
- eq: [status_code, 200]
- eq: [headers.Server, gunicorn/19.9.0]
- eq: [$.code, 0]

全局配置hooks, 那么该用例下所有的请求都会带上hooks

请求预处理钩子

如果需要对请求参数预处理,我们还新增了一个request 请求钩子,可以获取到发送请求时的request参数

在conftest.py

# 作者-上海悠悠 

def func1(req):
print(f'请求预处理:{req}')


def func2():
print(f'请求预处理-----------')


my_builtins.func1 = func1
my_builtins.func2 = func2

在 yaml 文件中使用示例

config:
name: post示例
teststeps:
-
name: post
request:
method: POST
url: http://httpbin.org/post
json:
username: test
password: "123456"
hooks:
request: ['func1', 'func2']
response: ['hook_response']
extract:
url: body.url
validate:
- eq: [status_code, 200]
- eq: [headers.Server, gunicorn/19.9.0]
- eq: [$.code, 0]
-
name: post
request:
method: POST
url: http://httpbin.org/post
json:
username: test
password: "123456"
hooks:
response: ['hook_response']
extract:
url: body.url
validate:
- eq: [status_code, 200]
- eq: [headers.Server, gunicorn/19.9.0]
- eq: [$.code, 0]

在config 中设置全局hooks示例

config:
name: post示例
hooks:
request: ['func1', 'func2']
response: ['hook_response']

由于request 变量是pytest的一个内置fixture,此变量保留着,获取请求参数的函数使用​​req​​​ 代替。
利用request hook功能可以实现请求参数的预处理,比如请求body签名和加密处理等需求。



举报

相关推荐

0 条评论