httprunner3.x詳細教程六(httprunner的setup和teardown及hook)
httprunner的setup和teardown可以在yml或者json文件中定義,按照3.x版本的推薦,建議大家在py文件中進行定義,unittest和pytest都可以定義setup和teardown,那么httprunner如何定義呢,下面我會介紹一下設置setup和teardown的兩種方式。
**歡迎加入測試交流群:自動化測試-夜行者(816489363)進行交流學習QAQ** --成都-阿木木
httprunner有兩種setup和teardown的定義方式,一個是測試類級別,一個是測試步驟級別的定義。
測試類級別的setup和teardown
第一種寫法setup和teardown:
- #!/user/bin/env python
- # -*- coding: utf-8 -*-
- """
- ------------------------------------
- @Project : interfaceDemo
- @Time : 2020/8/20 13:47
- @Auth : chineseluo
- @Email : 848257135@qq.com
- @File : demo_baidu_request_test.py
- @IDE : PyCharm
- ------------------------------------
- """
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
- class TestBaiduRequestTestCase(HttpRunner):
- def setup(self):
- print("運行於測試用例之前")
- def teardown(self):
- print("運行於測試用例之后")
- config = (
- Config("get user list")
- .base_url("https://www.baidu.com")
- .verify(False)
- )
- teststeps = [
- Step(
- RunRequest("get info")
- .get("/")
- .validate()
- .assert_equal("status_code", 200)
- )
- ]
- if __name__ == "__main__":
- TestBaiduRequestTestCase().test_start()
結果為:
- Process finished with exit code 0
- 運行於測試用例之前
- PASSED [100%]2020-08-20 13:50:53.306 | INFO | httprunner.loader:load_dot_env_file:127 - Loading environment variables from D:\TestScriptDir\httprunner\interfaceDemo\.env
- .
- .
- .
- D:\TestScriptDir\httprunner\interfaceDemo\logs\a3872c1b-dedf-4485-bd95-3f31947bfae0.run.log
- 運行於測試用例之后
第二種寫法setup_class和teardown_class:
- #!/user/bin/env python
- # -*- coding: utf-8 -*-
- """
- ------------------------------------
- @Project : interfaceDemo
- @Time : 2020/8/20 13:47
- @Auth : chineseluo
- @Email : 848257135@qq.com
- @File : demo_baidu_request_test.py
- @IDE : PyCharm
- ------------------------------------
- """
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
- class TestBaiduRequestTestCase(HttpRunner):
- @classmethod
- def setup_class(cls):
- print("運行於測試用例之前")
- @classmethod
- def teardown_class(cls):
- print("運行於測試用例之后")
- config = (
- Config("get user list")
- .base_url("https://www.baidu.com")
- .verify(False)
- )
- teststeps = [
- Step(
- RunRequest("get info")
- .get("/")
- .validate()
- .assert_equal("status_code", 200)
- )
- ]
- if __name__ == "__main__":
- TestBaiduRequestTestCase().test_start()
上面兩種寫法在unittest和pytest中是不一樣的,setup_class是運行於測試類的前面,setup是運行與每個測試方法的前面,在httprunner好像不區分這兩個方法。
測試步驟前后的setup和teardown設置
我在debugtalk.py中寫了兩個hook_up和hook_teardown方法
- def hook_up():
- print("前置操作:setup!")
- def hook_down(response=None):
- print("后置操作:teardown!")
- if response:
- print(response)
- response.status_code = 300
在demo_baidu_request_test.py中調用debugtalk的兩個hook方法,使用setup_hook()和teardown_hook()來加載我們自定義的hook:
- #!/user/bin/env python
- # -*- coding: utf-8 -*-
- """
- ------------------------------------
- @Project : interfaceDemo
- @Time : 2020/8/20 13:47
- @Auth : chineseluo
- @Email : 848257135@qq.com
- @File : demo_baidu_request_test.py
- @IDE : PyCharm
- ------------------------------------
- """
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
- class TestBaiduRequestTestCase(HttpRunner):
- @classmethod
- def setup_class(cls):
- print("運行於測試用例之前")
- @classmethod
- def teardown_class(cls):
- print("運行於測試用例之后")
- config = (
- Config("get user list")
- .base_url("https://www.baidu.com")
- .verify(False)
- )
- teststeps = [
- Step(
- RunRequest("get info")
- .setup_hook("${hook_up()}")
- .get("/")
- .teardown_hook("${hook_down()}")
- .validate()
- .assert_equal("status_code", 200)
- )
- ]
- if __name__ == "__main__":
- TestBaiduRequestTestCase().test_start()
運行結果:
- Process finished with exit code 0
- 運行於測試用例之前
- PASSED [100%]前置操作:setup!
- 后置操作:teardown!
- 2020-08-20 14:07:08.534 | INFO | httprunner.runner:test_start:460 - generate testcase log: D:\TestScriptDir\httprunner\interfaceDemo\logs\983886ea-36c1-4677-9966-4929f4006004.run.log
- 運行於測試用例之后
既然是hook方法,那么肯定是會集成一些內置的鈎子,滿足特殊的要求所使用的。
setup_hooks:在測試步驟前執行,先調用setup_hooks()內的函數。可以傳入 $request 參數,可以對請求進行預處理或者修改,修改請求參數
teardown_hooks:在測試步驟執行后,先調用teardown()內的函數,可以傳入$response參數,可以對返回值進行處理
我先在debugtalk.py中定義兩個方法,輸出一下后面獲取的request和response.
- def hook_up(request=None):
- print("輸出request:{}".format(request))
- print("前置操作:setup!")
- def hook_down(response=None):
- print("輸出response:{}".format('\n'.join(['%s:%s' % item for item in response.__dict__.items()])))
- print("后置操作:teardown!")
然后在demo_baidu_request_test.py文件中調用這兩個hook,然后傳遞參數$request和$response。
- #!/user/bin/env python
- # -*- coding: utf-8 -*-
- """
- ------------------------------------
- @Project : interfaceDemo
- @Time : 2020/8/20 13:47
- @Auth : chineseluo
- @Email : 848257135@qq.com
- @File : demo_baidu_request_test.py
- @IDE : PyCharm
- ------------------------------------
- """
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
- class TestBaiduRequestTestCase(HttpRunner):
- @classmethod
- def setup_class(cls):
- print("運行於測試用例之前")
- @classmethod
- def teardown_class(cls):
- print("運行於測試用例之后")
- config = (
- Config("get user list")
- .base_url("https://www.baidu.com")
- .verify(False)
- )
- teststeps = [
- Step(
- RunRequest("get info")
- .setup_hook("${hook_up($request)}")
- .get("/")
- .teardown_hook("${hook_down($response)}")
- .validate()
- .assert_equal("status_code", 200)
- )
- ]
- if __name__ == "__main__":
- TestBaiduRequestTestCase().test_start()
結果如下:
- Process finished with exit code 0
- 運行於測試用例之前
- PASSED [100%]輸出request:{'method': 'GET', 'url': '/', 'params': {}, 'headers': {'HRUN-Request-ID': 'HRUN-656566cb-5369-43b1-af19-47ce6ef1c7ba-081374'}, 'req_json': None, 'data': None, 'cookies': {}, 'timeout': 120, 'allow_redirects': True, 'verify': False}
- 前置操作:setup!
- resp_obj:<Response [200]>
- validation_results:{}
- 后置操作:teardown!
傳入的是一個request和response對象,我們可以對於傳入的request和response對象進行操作
我們可以修改resquest和response傳入和返回的值,來完成復雜的業務要求。
現在debugtalk.py改變了一下:
- def hook_up(request=None):
- print("輸出request:{}".format(request))
- print("前置操作:setup!")
- if request:
- request["params"]["username"] = "888888"
- def hook_down(response=None):
- print("輸出response:{}".format('\n'.join(['%s:%s' % item for item in response.__dict__.items()])))
- print("后置操作:teardown!")
- if response:
- response.status_code = 404
我修改了傳入的setp的密碼為“888888”,修改了step返回的狀態碼為404,看一下我在demo_baidu_request_test.py中的調用:
- #!/user/bin/env python
- # -*- coding: utf-8 -*-
- """
- ------------------------------------
- @Project : interfaceDemo
- @Time : 2020/8/20 13:47
- @Auth : chineseluo
- @Email : 848257135@qq.com
- @File : demo_baidu_request_test.py
- @IDE : PyCharm
- ------------------------------------
- """
- from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
- class TestBaiduRequestTestCase(HttpRunner):
- @classmethod
- def setup_class(cls):
- print("運行於測試用例之前")
- @classmethod
- def teardown_class(cls):
- print("運行於測試用例之后")
- config = (
- Config("get user list")
- .variables(
- **{
- "username": "123456"
- }
- )
- .base_url("https://www.baidu.com")
- .verify(False)
- )
- teststeps = [
- Step(
- RunRequest("get info")
- .setup_hook("${hook_up($request)}")
- .get("/")
- .with_params(**{"username": "${username}"})
- .teardown_hook("${hook_down($response)}")
- .validate()
- .assert_equal("status_code", 200)
- )
- ]
- if __name__ == "__main__":
- TestBaiduRequestTestCase().test_start()
下面是執行結果:
- demo_baidu_request_test.py::TestBaiduRequestTestCase::test_start <- C:\Users\luozhongwen\AppData\Local\Programs\Python\Python38\lib\site-packages\httprunner\runner.py 運行於測試用例之前
- FAILED [100%]輸出request:{'method': 'GET', 'url': '/', 'params': {'username': '123456'}, 'headers': {'HRUN-Request-ID': 'HRUN-bbeea383-94b1-43c4-8092-4f35debfdacc-782331'}, 'req_json': None, 'data': None, 'cookies': {}, 'timeout': 120, 'allow_redirects': True, 'verify': False}
- 前置操作:setup!
- 輸出response:resp_obj:<Response [200]>
- validation_results:{}
- 后置操作:teardown
- method : GET
- url : https://www.baidu.com/?username=888888
- httprunner.exceptions.ValidationFailure: assert status_code equal 200(int) ==> fail
- check_item: status_code
- check_value: 404(int)
- assert_method: equal
- expect_value: 200(int)
可以看到斷言是失敗的,我設置的成功斷言狀態碼是200,傳入的request中的username開始是123456,被我們截獲請求參數后更改為了888888。在實際應用中,我們可以對於傳入賬號密碼等進行加密,或者對於返回值的格式等進行解碼操作