一、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