httprunner3.x hook機制


 

接口自動化測試中,難免會出現前置條件和后置條件的處理問題,unittest框架中使用最多的是setUp() 、tearDown() ;pytest中使用最多的是在夾層 conftest.py 文件中定義函數加 @pytest.fixture() 裝飾器來處理;而httprunner中使用的是hook機制來處理前置后置。

 

在 .py文件的測試步驟的 teststeps 中新增關鍵字 setup_hook 和 teardown_hook:

import pytest
from httprunner import (HttpRunner, Config, Step, RunRequest, Parameters)


class TestCaseLogin(HttpRunner):

    @pytest.mark.parametrize('param', Parameters({"device_type": [1]}))
    def test_start(self, param):
        super().test_start(param)

    config = (
        Config("login")
        .base_url("${ENV(HOSTURL)}")
        .variables(
            **{"username": "${ENV(USERNAME)}",
               "password": "${ENV(PASSWORD)}",
               "company_id": "${ENV(COMPANYID)}"
               }
        )
        .verify(False)
    )
    teststeps = [
        Step(
            RunRequest('login')
            .with_variables(**{'token_length': 32, 'status_code': 201, 'status': 1})
            .setup_hook('${setup_hooks_request($request)}')
            .post('/client/user/auth')
            .with_headers(**{"Content-Type": "application/json"})
            .with_json({"scenario": "client", "company_id": '$company_id',
                        "user_name": "$username", "password": "$password",
                        "device_type": "$device_type", "device": ""})
            .teardown_hook('${teardown_assert_response($response)}')
            .extract()
            .with_jmespath("body.data.token", "token")
            .validate()
            .assert_equal('status_code', '$status_code', '斷言失敗')
            .assert_equal('body.status', '$status', '斷言失敗')
            .assert_length_equal('body.data.token', '$token_length', '斷言失敗')
        )
    ]


if __name__ == '__main__':
    TestCaseLogin().test_start()

 

  • setup_hook :是在請求發出前運行,主要用於處理接口的前置的准備工作,也可以對請求參數修改校驗等
  • teardown_hook:是在請求發出后運行,主要用於處理接口后置的清理工作,也可以對返回值進行修改、字段校驗等

 

在 debugtalk.py文件中定義hook函數,hook函數其實也就是普通函數,只要符合函數編寫規范即可:

def setup_hooks_request(request):
    user_agent = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                                'Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54'}
    header = {'Content-Type': 'application/json', 'User-Agent': user_agent}
    if 'headers' in request:
        if bool(request['headers']) is True:
            request['headers'].update(user_agent)
        else:
            request['headers'].update(header)
    else:
        request['headers'] = header
    print('前置條件執行完成')


def teardown_assert_response(response):
    if response.status_code == 200 or 201:
        if response.body['status'] == 1:
            print('接口訪問成功')
    else:
        print('接口請求失敗')
    print('后置條件執行完成')

 

  1. 定義的 setup_hooks_request 前置條件是處理接口頭信息是否加了 User-Agent 參數
  2. 定義的 teardown_assert_response 后置條件是處理返回的http狀態碼及接口成功與否的狀態碼status
  3. httprunner為了應用更復雜的場景,定義的hook函數中的位置參數可以和用例的請求參數、響應值作關聯;我們只需要把 request、response 放在定義好的hook函數位置參數上即可;當然定義的hook函數的位置參數,你也可以自定義其名稱,但還是推薦規范操作。 

 

用例中引用時要遵循規則,前置調用 setup_hook('${setup_hooks_request($request)}');后置調用 teardown_hook('${teardown_assert_response($response)}'),實際還是我們自己定義的hook函數放在httprunner庫中內置的hook函數中執行

  • $request 、$response 就是我們傳入定義的hook函數中位置參數的值,這兩個是固定的,修改成其他的是會報錯的
    teststeps = [
        Step(
            RunRequest('login')
            .with_variables(**{'token_length': 32, 'status_code': 201, 'status': 1})
            .setup_hook('${setup_hooks_request($request)}')
            .post('/client/user/auth')
            .with_headers(**{"Content-Type": "application/json"})
            .with_json({"scenario": "client", "company_id": '$company_id',
                        "user_name": "$username", "password": "$password",
                        "device_type": "$device_type", "device": ""})
            .teardown_hook('${teardown_assert_response($response)}')
            .extract()
            .with_jmespath("body.data.token", "token")
            .validate()
            .assert_equal('status_code', '$status_code', '斷言失敗')
            .assert_equal('body.status', '$status', '斷言失敗')
            .assert_length_equal('body.data.token', '$token_length', '斷言失敗')
        )
    ]

 

運行 hrun testcase_student_login_test.py -s 命令,控制台看下部分運行結果:

F:\TESTING\apiWebStudent\demo\testcases>hrun testcase_student_login_test.py -s
================================================================================= test session starts =================================================================================
collected 1 item                                                                                                                                                                       

testcase_student_login_test.py 2021-03-26 18:53:34.028 | INFO     | httprunner.runner:test_start:451 - Start to run testcase: login, TestCase ID: de9cc10c-9cde-474e-a86c-2c167d42dafb
2021-03-26 18:53:34.030 | INFO     | httprunner.runner:__run_step:292 - run step begin: login >>>>>>
2021-03-26 18:53:34.031 | INFO     | httprunner.runner:__call_hooks:112 - call hook actions: setup request
2021-03-26 18:53:34.033 | DEBUG    | httprunner.runner:__call_hooks:121 - call hook function: ${setup_hooks_request($request)}
前置條件執行完成
2021-03-26 18:53:34.177 | DEBUG    | httprunner.client:request:186 - client IP: 10.10.12.173, Port: 49977
2021-03-26 18:53:34.179 | DEBUG    | httprunner.client:request:194 - server IP: 112.17.250.185, Port: 443
2021-03-26 18:53:34.184 | INFO     | httprunner.client:request:218 - status_code: 201, response_time(ms): 143.01 ms, response_length: 0 bytes
2021-03-26 18:53:34.185 | INFO     | httprunner.runner:__call_hooks:112 - call hook actions: teardown request
2021-03-26 18:53:34.186 | DEBUG    | httprunner.runner:__call_hooks:121 - call hook function: ${teardown_assert_response($response)}
接口訪問成功
后置條件執行完成
2021-03-26 18:53:34.188 | INFO     | httprunner.response:extract:176 - extract mapping: {'token': 'f200bbc22c2036957ff13fb62f382b24'}
2021-03-26 18:53:34.189 | INFO     | httprunner.response:validate:246 - assert status_code equal 201(int)       ==> pass
2021-03-26 18:53:34.190 | INFO     | httprunner.response:validate:246 - assert body.status equal 1(int) ==> pass
2021-03-26 18:53:34.191 | INFO     | httprunner.response:validate:246 - assert body.data.token length_equal 32(int)     ==> pass
2021-03-26 18:53:34.192 | INFO     | httprunner.runner:__run_step:304 - run step end: login <<<<<<

2021-03-26 18:53:34.193 | INFO     | httprunner.runner:test_start:460 - generate testcase log: F:\TESTING\apiWebStudent\demo\logs\de9cc10c-9cde-474e-a86c-2c167d42dafb.run.log
.

================================================================================== 1 passed in 0.29s ==================================================================================
Sentry is attempting to send 0 pending error messages
Waiting up to 2 seconds
Press Ctrl-Break to quit

 

以上總結或許能幫助到你,或許幫助不到你,但還是希望能幫助到你,如有疑問、歧義,評論區留言會及時修正發布,謝謝!

 



未完,待續…

一直都在努力,希望您也是!

 

轉載請附帶原文鏈接 ( https://www.cnblogs.com/lifeng0402/articles/14583475.html ),否則追究法律責任,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM