当我们在使用pytest实现前后置调用时有两种方式
方式一:
采用setup/teardown以及setup_class/teardown_class类似这种方式去实现前后置调用
方式二:
采用pytest中强大的fixture装饰器来实现
本期文章主要采用方式二来解决测试用例前后置调用的问题
首先我们来看下,pytest中的fixture的参数有哪些,分别是scope,params,autouse,ids,name这5个形参,哪些他们分别的作用域以及作用是什么呢?
下面来说下scope:
“”“
scope:
function(默认)
class
module
session
params:
参数化,支持list,tuple,字典列表,字典元组
autouse:
false(默认)
True
ids:
当使用params参数化时,给每一个值设置一个变量名,其实意义不大
name:
表示的是被@pytest.fixture标记的方法取一个别名,注意:当去了别名之后,原来的名称无法使用
”“”
@pytest.fixture(scope='function')
def my_fixture():
print('这是前置内容')
yield
print('这是后置内容')
class Testdemo():
def test01(self,my_fixture):
print('这是test01')
def test02(self):
print('这是test02')
根据上面的结构,运行后输出的内容为
这是前置内容
这是test01
这是后置内容
这是前置内容
这是test02
这是后置内容
对于上述方法中传入my_fixture的做法,主要是对比setup/teardown之类的更方便,不需要每个方法都在运行之前执行一边setup,而是在某个方法需要这种操作时在执行
下面来说下autouse:
这个参数的使用,主要是弥补如果想使用scope,必须传入my_fixture的缺陷,当引入autouse时,默认是false,我们将false更新为True,此时被fixture装饰的方法将会自动传入每个测试用例方法中,不需要自己传入my_fixture
import pytest
@pytest.fixture(scope='function',autouse=True)
def my_fixture():
print('这是前置内容')
yield
print('这是后置内容')
class Testdemo():
def test_01(self):
print('这是test01')
def test_02(self):
print('这是test02')
输出结果为:
testcase/demo1/test_func3.py::Testdemo::test_01 这是前置内容
这是test01
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_02 这是前置内容
这是test02
PASSED这是后置内容
下面来说下params:
主要作用是参数化
import pytest
@pytest.fixture(scope='function',params=['tom1','tom2'],autouse=True)
def my_fixture(request):
print('这是前置内容')
yield request.param
print('这是后置内容')
class Testdemo():
def test_01(self,my_fixture):
print('这是test01',my_fixture)
def test_02(self):
print('这是test02')
输出结果:
testcase/demo1/test_func3.py::Testdemo::test_01[tom1] 这是前置内容
这是test01 tom1
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_01[tom2] 这是前置内容
这是test01 tom2
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_02[tom1] 这是前置内容
这是test02
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_02[tom2] 这是前置内容
这是test02
PASSED这是后置内容
这里需要强调的是:
1:params中传入几个值,对应的测试用例就会运行几次,比如传入了两个值tom1和tom2,那么对应测试用例test01和test02就会分别运行两次,这个可以从结果中看到
2:params中传入的值是可以获取到的,通过request.param来获取,并返回给用例中传入的my_fixture,我们从结果中的输出就能看到test01比test02多输出了params的值
下面来说下ids:
主要作用是给params中每一个值设置一个变量名,如果params传入的是中文,这个ids可能会用到,其余情况很少会用,因为如果params传入的是中文,那么request.param返回的可能会有编码
import pytest
@pytest.fixture(scope='function',params=['汤姆1','汤姆2'],autouse=True,ids=['tom1','tom2'])
def my_fixture(request):
print('这是前置内容')
yield request.param
print('这是后置内容')
class Testdemo():
def test_01(self,my_fixture):
print('这是test01',my_fixture)
def test_02(self):
print('这是test02')
输出的结果:
testcase/demo1/test_func3.py::Testdemo::test_01[tom1] 这是前置内容
这是test01 汤姆1
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_01[tom2] 这是前置内容
这是test01 汤姆2
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_02[tom1] 这是前置内容
这是test02
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_02[tom2] 这是前置内容
这是test02
PASSED这是后置内容
上面所说的乱码会出现在每个用例名称后面的【】中,加了ids就会在【】中显示对应新的变量名
下面来说下name:
主要是给被fixture装饰的方法取个别名,后面测试用例使用时,传别名就行,原来的名称是无效的
import pytest
@pytest.fixture(scope='function',params=['汤姆1','汤姆2'],autouse=False,ids=['tom1','tom2'],name='demo')
def my_fixture(request):
print('这是前置内容')
yield request.param
print('这是后置内容')
class Testdemo():
def test_01(self):
print('这是test01')
def test_02(self,demo):
print('这是test02',demo)
输出结果:
testcase/demo1/test_func3.py::Testdemo::test_01 这是test01
PASSED
testcase/demo1/test_func3.py::Testdemo::test_02[tom1] 这是前置内容
这是test02 汤姆1
PASSED这是后置内容
testcase/demo1/test_func3.py::Testdemo::test_02[tom2] 这是前置内容
这是test02 汤姆2
PASSED这是后置内容
从上面可以看出,我传入的被fixture装饰的函数不是my_fixture,而是别名demo