一、fixture优势
1、fixture相对于setup和teardown来说应该有以下几点优势:
命名方式灵活,不局限于setup和teardown这几个命名
conftest.py配置里可以实现数据共享,不需要import就能自动找到一些配置
scope="module"可以实现多个.py跨文件共享前置
scope="session"以实现多个.py跨文件使用一个session来完成多个用例
2、使用装饰器标记fixture的功能
fixture(scope="function",params=None,autouse=False,ids=None,name=None)
可以使用此装饰器(带或不带参数)来定义fixture功能。fixture功能的名称可以在以后使用,引用它会在运行测试之前调用它:
test模块或类可以使用pytest.mark.usefixtures(fixturename)标记
测试功能可以直接使用fixture名称作为输入参数,在这种情况下,夹具实例从fixture返回功能将被注入
二、fixture参数介绍
fixture(scope="function",params=None,autouse=False,ids=None,name=None)
1、scope
scope参数有四个级别参数:"function"(默认)、"class"、"module"、"session"
2、params
一个可选的参数列表,它将导致多个参数调用fixture功能和所有测试使用它
3、autouse
如果为True,则为所有测试激活fixture func 可以看到它
如果为False(默认值),则显式需要参考来激活fixture
4、ids
每个字符串id的列表,每个字符串对应于params,这样他们就是测试ID的一部分,如果没有提供ID它们将从params自动生成
5、name
fixture的名称,这默认为装饰函数的名称。如果fixture在定义它的同一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽;解决这个问题的一种方法是将装饰函数命名"fixture_<fixturename>",然后使用"@pytest.fixture(name='<fixturename>')"
备注:fixtures可以选择使用yield语句为测试函数提供它们的值,而不是return。在这种情况下,yield语句之后的代码块作为拆卸代码执行,而不管测试结果如何。fixture功能必须只产生一次
三、fixture参数传入(scope="function")
1、实现场景:用例1需要先登录,用例2不需要登录,用例3需要先登录
#!encoding=utf-8 import pytest #不带参数时默认scope="function" @pytest.fixture() def login(): print("输入账号,密码先登录") def test_s1(login): print('用例1:登录之后其他动作111') def test_s2(): #不传login print('用例2:不需要登录,操作222') def test_s3(login): print('用例3:登录之后其他动作333') if __name__=="__main__": pytest.main('-s test_class004.py')
运行结果:
2、如果@pytest.fixture()里面没有参数,那么默认scope="function",也就是此时的级别的function,针对函数有效
3、在test用例当中加入了login参数之后,那么在运行用例之前会先运行fixture装饰器内的函数login
四、fixture参数传入(scope="module")
1、fixture参数scope="module",module作用是整个.py文件都会生效,用例调用时,参数写上函数名称就行
#!encoding=utf-8 import pytest @pytest.fixture(scope="module") def open(): print("打开浏览器,并且打开百度首页") def test_s1(open): print("执行用例1") def test_s2(open): print("执行用例2") def test_s3(open): print("执行用例3") if __name__=="__main__": pytest.main('-s test_class005.py')
运行结果:
从结果看出,虽然test_s1、test_s2、test_s3三个地方调用了open函数,但是它只会在第一个用例执行前执行一次
2、如果test_s1不调用,test_s2调用open函数,test_s3不调用,运行顺序会怎么样?
#!encoding=utf-8 import pytest @pytest.fixture(scope="module") def open(): print("打开浏览器,并且打开百度首页") def test_s1(): print("执行用例1") def test_s2(open): print("执行用例2") def test_s3(): print("执行用例3") if __name__=="__main__": pytest.main('-s test_class005.py')
运行结果:
从结果看出,module级别的fixture在当前.py模块里,只会在用例第一次调用前执行一次
五、conftest.py配置
1、上面的案例是在同一个.py文件中,多个用例调用一个登录功能,如果有多个.py的文件都需要调用这个登陆功能的话,那就不能把登陆写到用例里面去,此时应该要有一个配置文件,单独管理一些预置的操作场景,pytest里面默认读取conftest.py里面的配置
conftest.py配置需要注意以下几点:
conftest.py配置脚本名称是固定的,不能修改名称
conftest.py与运行的用例要在同一个package下,并且有init.py文件(亲测conftest.py只要在运行用例文件的上级目录或者在同一个package都可以被调用到,不一定非要在同一个package当中,可以调整conftest.py的位置进行测试)
不需要import导入conftest.py,pytest用例会自动查找
#conftest.py #!encoding=utf-8 import pytest @pytest.fixture() def login(): print('输入账号,密码先登录') @pytest.fixture() def open_index(): print('打开首页')
#test_fix1.py #!encoding=utf-8 import pytest def test_s1(login): print('用例1:登录之后其他动作111') def test_s2(open_index): print('用例2:打开首页操作,操作222') def test_s3(login): print('用例3:登录之后其他动作333') if __name__=="__main__": pytest.main('-s test_fix1.py')
#test_fix2.py #!encoding=utf-8 import pytest def test_s4(login): print('用例4:登录之后其他动作111') def test_s5(open_index): print('用例5:打开首页操作,操作222') if __name__=="__main__": pytest.main('-s test_fix2.py')
执行test_fix1.py
执行test_fix2.py
2、单独运行test_fix1.py与test_fix2.py都能调用到conftest.py当中的fixture装饰器中的方法,这样就能实现一些公共的操作可以单独被调用
3、如果.py文件调用conftest.py调用不到时会报以下错误
==================================== ERRORS ==================================== __________________________ ERROR at setup of test_s1 ___________________________ file /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py, line 4 def test_s1(login): E fixture 'login' not found > available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, metadata, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory > use 'pytest --fixtures [testpath]' for help on them. /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py:4 __________________________ ERROR at setup of test_s2 ___________________________ file /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py, line 7 def test_s2(open_index): E fixture 'open_index' not found > available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, metadata, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory > use 'pytest --fixtures [testpath]' for help on them. /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py:7 __________________________ ERROR at setup of test_s3 ___________________________ file /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py, line 10 def test_s3(login): E fixture 'login' not found > available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, metadata, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory > use 'pytest --fixtures [testpath]' for help on them. /Users/luozelin/Desktop/pytest/pytest_demo/test_fix1.py:10 =============================== 3 error in 0.03s ===============================
参考原文链接:https://blog.csdn.net/BearStarX/article/details/101000516