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。在实际应用中,我们可以对于传入账号密码等进行加密,或者对于返回值的格式等进行解码操作