上一节中,我们总揽性的介绍了unittest和pytest的区别与联系。本节将详细介绍pytest框架中前置、后置的声明和调用。
pytest在前置后置的设置上,有2种比较常用的方式,分别是:
方式一:沿用unittest的风格
方式二:使用fixture -- 本节介绍的主要内容
使用fixture设置前后置比较鲜明的特点是:先定义,后调用
一、前置后置的定义
1、使用函数进行实现的,函数名称不固定。
Q:如何确定定义的函数就是前置后置呢?
A:在定义的函数上添加装饰器:@pytest.fixture
1 @pytest.fixture
2 def init():
3 pass
2、前置后置操作写在同一函数里,无需分开写在不同的函数中,其中前置后置操作使用yield进行区分
1 @pytest.fixture
2 def init():
3 前置操作代码
4 yield
5 后置操作代码
3、前置后置作用域的设置
源码中提供了5个作用域,分别是:测试函数(function)、测试类(class)、测试模块(module)、测试会话(session)和测试包(package)
实际应用中,比较常见的是前面4种,即测试函数(function)、测试类(class)、测试模块(module)、测试会话(session)
1 @pytest.fixture(scope=function(默认值)/class/module/session)
2 def init():
3 前置操作代码
4 yield
5 后置操作代码
【说明】
框架默认的作用域的测试函数级别的,通过修改装饰器中scope的值可以修改前置后置的作用域。
4、参数传递
当我们的测试用例中需要使用前置操作中得到的某些数据时,可以借助yield实现参数的传递,如
yield 返回参数
【说明】
(1)当返回的参数有多个时,pytest框架默认将这些参数打包成元组的形式;
(2)测试用例中获取前置操作中返回的参数:以fixture函数名作为用例参数,用于接收前置中的返回值。
5、共享机制:conftest.py -- 模块名称必须是conftest
我们在conftest.py中可以定义多个fixture,便于测试用例共享这些前置后置操作
6、存放位置
由于测试用例在使用前置后置时需要进行调用,因此其存放位置比较灵活,可以不用跟测试类/测试函数存放在一起。
二、前置后置的调用
测试用例需要前置后置时,可以主动调用预先定义的前置后置,即“哪儿需要哪儿调用”
【语法】
1 @pytest.mark.usefixtures("fixture的函数名称")
2 测试类/测试函数
【说明】
如果fixture中有返回值时,并且测试用例中需要使用这些返回值时,则可以不用使用@pytest.mark.usefixtures("fixture的函数名称")
但是为了书写一致性,建议还是写上。
附录
1 import pytest
2
3 """
4 定义前置、后置函数
5 """
6 # 默认的作用域scope = function
7 @pytest.fixture() # 不带返回值
8 def init():
9 print("**********前置函数********")
10 yield
11 print("**********后置函数********")
12
13 @pytest.fixture() # 带返回值
14 def init1():
15 print("**********前置函数111********")
16 yield "我带返回值"
17 print("**********后置函数111********")
18
19
20 @pytest.fixture(scope="class")
21 def init_class():
22 print("----------前置类函数----------")
23 yield True,"hello world"
24 print("----------后置类函数----------")
25
26 """
27 调用前置、后置函数
28 """
29
30 @pytest.mark.usefixtures("init")
31 def test_demo1():
32 print("测试用例1")
33
34 @pytest.mark.usefixtures("init1")
35 def test_demo2(init1):
36 print("测试用例2")
37 print(init1)
38
39
40 @pytest.mark.usefixtures("init_class")
41 class TestDemo:
42
43 def test_demo3(self):
44 print("测试用例3")
45
46 def test_demo4(self,init_class): # 返回的值为元组
47 print("测试用例4")
48 print(init_class)