httprunner 3.x学习13 - hook 机制

前言

httprunner 3.x可以支持hook机制,在发送请求前做一些预处理或在请求完成后后置处理

  • setup_hook :主要用于处理接口的前置的准备工作,也可以对请求 request 参数签名加密等操作

  • teardown_hook:主要用于后置清理工作,也可以对返回 respone 解密等操作

测试步骤添加hook

# debugtalk.py
# 上海悠悠,QQ交流群:750815713
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

def hook_up():
print("前置操作:setup!")

def hook_down():
print("后置操作:teardown!")

只在第一个步骤添加 setup_hooksteardown_hooks

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

config:
name: logincase
base_url: ${ENV(base_url)}
variables: {}
export:
- token

teststeps:
-
name: step1 login
request:
url: /api/v1/login/
method: POST
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
json:
username: test
password: 123456
setup_hooks:
- ${hook_up()}
teardown_hooks:
- ${hook_down()}
extract:
token: content.token # 提取token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.msg, login success!]
- eq: [content.code, 0]

对应的pytest脚本

# NOTE: Generated By HttpRunner v3.1.4
# FROM: testcases\demo_hook.yml
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase

class TestCaseDemoHook(HttpRunner):

config = Config("logincase").base_url("${ENV(base_url)}").export(*["token"])

teststeps = [
Step(
RunRequest("step1 login")
.setup_hook("${hook_up()}")
.post("/api/v1/login/")
.with_headers(
**{
"Content-Type": "application/json",
"User-Agent": "python-requests/2.18.4",
}
)
.with_json({"username": "test", "password": 123456})
.teardown_hook("${hook_down()}")
.extract()
.with_jmespath("body.token", "token")
.validate()
.assert_equal("status_code", 200)
.assert_equal('headers."Content-Type"', "application/json")
.assert_equal("body.msg", "login success!")
.assert_equal("body.code", 0)
),
]

if __name__ == "__main__":
TestCaseDemoHook().test_start()

从运行结果可以看到,setup_hooks 在 request 请求之前执行,teardown_hooks 在 response 之后,assert 断言之前执行

testcases\demo_hook_test.py 2021-06-21 18:45:17.051 | INFO | httprunner.runner:test_start:451 -
Start to run testcase: logincase, TestCase ID: 8043485f-1c2f-4e00-b00b-f951dc8cf6fa
2021-06-21 18:45:17.054 | INFO | httprunner.runner:__run_step:292 - run step begin: step1 login >>>>>>
2021-06-21 18:45:17.056 | INFO | httprunner.runner:__call_hooks:112 - call hook actions: setup request
2021-06-21 18:45:17.056 | DEBUG | httprunner.runner:__call_hooks:121 - call hook function: ${hook_up()}
前置操作:setup!
2021-06-21 18:45:17.197 | DEBUG | httprunner.client:request:186 - client IP: 192.168.1.125, Port: 30848
2021-06-21 18:45:17.200 | DEBUG | httprunner.client:request:194 - server IP: 49.235.92.12, Port: 8201
2021-06-21 18:45:17.202 | DEBUG | httprunner.client:log_print:40 -
....
2021-06-21 18:45:17.205 | INFO | httprunner.client:request:218 - status_code: 200, response_time(ms): 139.3 ms, response_length: 0 bytes
2021-06-21 18:45:17.207 | INFO | httprunner.runner:__call_hooks:112 - call hook actions: teardown request
2021-06-21 18:45:17.210 | DEBUG | httprunner.runner:__call_hooks:121 - call hook function: ${hook_down()}
后置操作:teardown!
2021-06-21 18:45:17.211 | INFO | httprunner.response:extract:176 - extract mapping: {'token': '392cb8c08440bde6f7ed72745e052a5c3f090aff'}
2021-06-21 18:45:17.213 | INFO | httprunner.response:validate:246 - assert status_code equal 200(int) ==> pass
...

请求 request 预处理

针对请求request 发出去的参数预处理,也可以用到 setup_hooks,需传一个内置 request 参数,debugtalk.py代码如下

# debugtalk.py
def request_sign(request):
"""请求sign签名"""
print("请求body:",request.get("req_json"))
# 新增 sign 参数
request["req_json"]["sign"] = "sign xxxxxxxxxxxxxxx"
print("sign 签名后请求body:", request.get("req_json"))

yaml脚本引用函数${request_sign($request)}

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

config:
name: logincase
base_url: ${ENV(base_url)}
variables: {}
export:
- token

teststeps:
-
name: step1 login
request:
url: /api/v1/login/
method: POST
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
json:
username: test
password: 123456
setup_hooks:
- ${request_sign($request)}
extract:
token: content.token # 提取token
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.msg, login success!]
- eq: [content.code, 0]

pytest脚本

# NOTE: Generated By HttpRunner v3.1.4
# FROM: testcases\demo_hook.yml
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase

class TestCaseDemoHook(HttpRunner):

config = Config("logincase").base_url("${ENV(base_url)}").export(*["token"])

teststeps = [
Step(
RunRequest("step1 login")
.setup_hook("${request_sign($request)}")
.post("/api/v1/login/")
.with_headers(
**{
"Content-Type": "application/json",
"User-Agent": "python-requests/2.18.4",
}
)
.with_json({"username": "test", "password": 123456})
.extract()
.with_jmespath("body.token", "token")
.validate()
.assert_equal("status_code", 200)
.assert_equal('headers."Content-Type"', "application/json")
.assert_equal("body.msg", "login success!")
.assert_equal("body.code", 0)
),
]

if __name__ == "__main__":
TestCaseDemoHook().test_start()

运行后查看日志可以看到,已经签名成功

请求body: {'username': 'test', 'password': 123456}
sign 签名后请求body: {'username': 'test', 'password': 123456, 'sign': 'sign xxxxxxxxxxxxxxx'}
2021-06-21 18:58:57.876 | DEBUG | httprunner.client:request:186 - client IP: 192.168.1.125, Port: 31471
2021-06-21 18:58:57.878 | DEBUG | httprunner.client:request:194 - server IP: 49.235.92.12, Port: 8201
2021-06-21 18:58:57.881 | DEBUG | httprunner.client:log_print:40 -
================== request details ==================
method : POST
url : http://127.0.0.1:8000/api/v1/login/
headers : {
"User-Agent": "python-requests/2.18.4",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Connection": "keep-alive",
"Content-Type": "application/json",
"HRUN-Request-ID": "HRUN-911bb03a-a24a-40a6-ad32-9d62a9d000fd-137716",
"Content-Length": "72"
}
cookies : {}
body : {
"username": "test",
"password": 123456,
"sign": "sign xxxxxxxxxxxxxxx"
}

返回 response 处理

如果需要在接口返回后,对返回的结果处理,可以添加respone请求参数,比如我把返回的状态码200改成了203

# debugtalk.py
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

def response_status(response):
"""修改返回状态码"""
print("返回response status_code:", response.status_code)
response.status_code = 203
print("修改后返回response status_code:", response.status_code)

yaml 引用示例

setup_hooks:
- ${request_sign($request)}
teardown_hooks:
- ${response_status($response)}

pytest引用示例

.with_json({"username": "test", "password": 123456})
.teardown_hook("${response_status($response)}")

运行结果

2021-06-21 19:07:13.729 | INFO | httprunner.client:request:218 - status_code: 200, response_time(ms): 157.17 ms, response_length: 0 bytes
2021-06-21 19:07:13.731 | INFO | httprunner.runner:__call_hooks:112 - call hook actions: teardown request
2021-06-21 19:07:13.736 | DEBUG | httprunner.runner:__call_hooks:121 - call hook function: ${response_status($response)}
返回response status_code: 200
修改后返回response status_code: 203

httprunner 3.x 版本在 config 中不支持setup_hookteardown_hook

2021年第八期《python接口web自动化+测试开发》7.17号开学(课程全面升级!) 加量不加价(新增postman, 赠送selenium和python基础2个课)

本期上课时间:7月17号-10月16号,每周六、周日晚上20:30-22:30

(0)

相关推荐

  • 当语音助手遇到机器人

    来源:Python 技术「ID: pythonall」 当语音助手遇到机器人 大家都知道现在智能手机都有语音助手,Mac 有 Siri,Windows 有小冰,那么这些语音助手遇到机器人会发生哪些有趣 ...

  • 小游戏:换脸术

    最近估计大家都陆陆续续的复工了,大家经常在节后会得一个叫做节后综合征的病,具体表现为:提不起精神.上班效率低.没精神,严重的还会出现恶心.焦虑.神经衰落等等.这里给大家带来一个小游戏娱乐一下,放松上班 ...

  • 想升级研究思路?那赶快学习下这个机制

    解螺旋公众号·陪伴你科研的第2559天 癌症的阿克琉斯之踵? 基因突变,肿瘤发生发展的重要原因之一.但由于很多导致基因功能缺失在内的大部分肿瘤相关突变都不是传统小分子药物或者抗体等生物类药物的直接作用 ...

  • httprunner 2.x学习5-测试用例集(testsuite)

    前言 httprunner 分层主要是分三层:api.testcase.testsuites 前面讲分层的时候讲到api单独封装每个接口,testcase可以有多个测试步骤,调用api层的接口是写测试 ...

  • httprunner 2.x学习4-测试用例分层

    前言 httprunner 2.x版本最大的改进就是分层机制了,1.x的版本是线性设计的,每个用例都是独立的. 一个用例里面涉及到流程性的,我们测试修改个人信息是否修改成功,在yaml文件里面需写3个 ...

  • httprunner 2.x学习3-variables变量声明与引用

    前言 在 HttpRunner 中,支持变量声明(variables)和引用($var)的机制.在 config 和 test 中均可以通过 variables 关键字定义变量,然后在测试步骤中可以通 ...

  • httprunner 2.x学习2-extract提取token值参数关联

    前言 如何将上个接口的返回token,传给下个接口当做请求参数?这是最常见的一个问题了. 解决这个问题其实很简单,我们只需取出token值,设置为一个中间变量a,下个接口传这个变量a就可以了.那么接下 ...

  • httprunner 2.x学习1-环境与登录接口案例

    前言 由于之前写过一个 httprunner 系列是针对 1.5.8 版本写的教程, httprunner版本更新的还挺快的,最近已经到3.x版本了,看了下改动还是挺大的. 但是考虑到目前还是有很多公 ...

  • httprunner 2.x学习9-生成测试报告ExtentReport

    前言 httprunner 可以自定义生成测试报告的模板,1.x版本里面有个 extent_report_template.html 模块非常美观. 但是生成报告的时候会报错:jinja2.excep ...

  • httprunner 2.x学习8-参数化(引用 debugtalk 函数)

    前言 httprunner 参数化数据源指定支持三种方式: 在 YAML/JSON 中直接指定参数列表:该种方式最为简单易用,适合参数列表比较小的情况 通过内置的 parameterize(可简写为P ...

  • httprunner 2.x学习7-参数化(引用外部csv数据)

    前言 httprunner 参数化数据源指定支持三种方式: 在 YAML/JSON 中直接指定参数列表:该种方式最为简单易用,适合参数列表比较小的情况 通过内置的 parameterize(可简写为P ...