fixture是pytest的一个闪光点,pytest要精通怎么能不学习fixture呢?跟着我一起深入学习fixture吧。其实unittest和nose都支持fixture,但是pytest做得更炫。 fixture是pytest特有的功能,它用pytest.fixture标识,定义在函数前面。在你编写测试函数的时候,你可以将此函数名称做为传入参数,pytest将会以依赖注入方式,将该函数的返回值作为测试函数的传入参数。 fixture有明确的名字,在其他函数,模块,类或整个工程调用它时会被激活。 fixture是基于模块来执行的,每个fixture的名字就可以触发一个fixture的函数,它自身也可以调用其他的fixture。 我们可以把fixture看做是资源,在你的测试用例执行之前需要去配置这些资源,执行完后需要去释放资源。比如module类型的fixture,适合于那些许多测试用例都只需要执行一次的操作。 fixture还提供了参数化功能,根据配置和不同组件来选择不同的参数。 fixture主要的目的是为了提供一种可靠和可重复性的手段去运行那些最基本的测试内容。比如在测试网站的功能时,每个测试用例都要登录和退出,利用fixture就可以只做一次,否则每个测试用例都要做这两步也是冗余。
把一个函数定义为Fixture很简单,只能在函数声明之前加上“@pytest.fixture”。其他函数要来调用这个Fixture,只用把它当做一个输入的参数即可。 test_fixture_basic.py
import pytest @pytest.fixture() def login(): print('login') return 'token' def test_case1(login): print(f'登录的操作的返回值是:{login}') print('case1')
下面是运行结果,test_case11运行之前调用了login
import pytest @pytest.fixture() def test1(): print('\n开始执行function') @pytest.mark.usefixtures('test1') def test_a(): print('---用例a执行---')
执行结果
fixture decorator一个optional的参数是autouse, 默认设置为False。 当默认为False,就可以选择用上面两种方式来试用fixture。 当设置为True时,在一个session内的所有的test都会自动调用这个fixture。 权限大,责任也大,所以用该功能时也要谨慎小心。
import pytest # autouse= True 自动应用, autouse 默认是FALSE @pytest.fixture() def other(): print('other') @pytest.fixture(autouse=True) def login(other): print('login') return other # 测试步骤 连接数据库 @pytest.fixture() def get_cookies(): print('get cookies') return 'cookies' def test_case1(get_cookies): print('case1') def test_case2(): print('case2') def test_case3(): print('case3')
执行结果: 从结果上可以看出来, 在执行所有的测试用例都调用了login,只有test_case1调用了get_cookies
function:每个test都运行,默认是function的scope class:每个class的所有test只运行一次 module:每个module的所有test只运行一次 session:每个session只运行一次
比如你的所有test都需要连接同一个数据库,那可以设置为module,只需要连接一次数据库,对于module内的所有test,这样可以极大的提高运行效率。
在上面的例子中,fixture返回值都是默认None,我们可以选择让fixture返回我们需要的东西。如果你的fixture需要配置一些数据,读个文件,或者连接一个数据库,那么你可以让fixture返回这些数据或资源。
如何带参数 fixture还可以带参数,可以把参数赋值给params,默认是None。对于param里面的每个值,fixture都会去调用执行一次,就像执行for循环一样把params里的值遍历一次。 test_fixture_param.py
import pytest @pytest.fixture(params=[1, 2, 3]) def get_data(request): return request.param def test_not_2(get_data): print('test_data: %s' % get_data) assert get_data != 2
运行结果