python學習-pytest(三)-fixture


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM