zoukankan      html  css  js  c++  java
  • httprunner 3.x学习13

    前言

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

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

    测试步骤添加hook

    在项目根目录新建debugtalk.py,名称一定要一样

    # debugtalk.py
    # 作者-上海悠悠 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: testcasesdemo_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 断言之前执行

    testcasesdemo_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: testcasesdemo_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

  • 相关阅读:
    ATL接口返回类型&&ATL接口返回字符串BSTR*
    不允许使用抽象类类型
    error C2039: 'SetDefaultDllDirectories'错误解决办法<转>
    directshow 虚拟摄像头 实例 代码解读
    UML建模之时序图(Sequence Diagram)<转>
    【干货】Chrome插件(扩展)开发全攻略(不点进来看看你肯定后悔)<转>
    在VS13上编译通过的代码放在12上编译-错误:l __dtoui3 referenced in function _event_debug_map_HT_GROW
    struct 方法使用
    2014华为机试题目
    贪心-poj-2437-Muddy roads
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/14914518.html
Copyright © 2011-2022 走看看