httprunner(setup和teardown及hook)

httprunner有两种setup和teardown的定义方式,一个是测试类级别,一个是测试步骤级别的定义。

测试类级别的setup和teardown
第一种写法setup和teardown:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/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中,如果编写链路型的参数化case,那么setup_class只会在首尾的用例中执行,中间几条用例是不会执行的,但是setup会在每一条用例中都执行。

测试步骤前后的setup和teardown设置
我在debugtalk.py中写了两个hook_up和hook_teardown方法

 

1
2
3
4
5
6
7
8
9
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/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.

1
2
3
4
5
6
7
8
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。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/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改变了一下:

1
2
3
4
5
6
7
8
9
10
11
12
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中的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/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。在实际应用中,我们可以对于传入账号密码等进行加密,或者对于返回值的格式等进行解码操作
————————————————
本文转自「成都 - 阿木木」,修改了一些结论,仅做交流学习
原文链接:https://blog.csdn.net/qq_39214101/article/details/108123635

posted @   HkGov  阅读(991)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示