接口自動化測試中,難免會出現前置條件和后置條件的處理問題,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('后置條件執行完成')
- 定義的 setup_hooks_request 前置條件是處理接口頭信息是否加了 User-Agent 參數
- 定義的 teardown_assert_response 后置條件是處理返回的http狀態碼及接口成功與否的狀態碼status
- 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 ),否則追究法律責任,謝謝!