1. 程式人生 > 其它 >pytest--fixture之conftest.py

pytest--fixture之conftest.py

前言

上一篇講到用例加setup和teardown可以實現在測試用例之前或之後加入一些操作,但這種是整個指令碼全域性生效的.

如果我想實現以下場景:

​ 用例1需要先登入,用例2不需要登入,用例3需要登入。很現實這就無法用setup和teardown來實現了。

這就是本篇學習的目的,自定義測試用例的預置條件。

fixture優勢

1.fixture相對於setupteardown來說應該有以下幾點優勢

  ● 命名方式靈活,不侷限於setup和teardwon這幾個命名。

  ● conftest.py配置裡可以實現資料共享,不需要import就能自動找到一些配置。

  ● scope="module"

可以實現多個.py跨檔案共享前置,每一個.py檔案呼叫一次。

  ● scope="session"以實現多個.py跨檔案使用一個session來完成多個用例。

Pycharm中輸入@pytest.fixture(),按住Ctrl+滑鼠左鍵,既可檢視fixture原始碼

fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    """使用裝飾器標記fixture的功能
     可以使用此裝飾器(帶或不帶引數)來定義fixture功能。 fixture功能的名稱可以在以後使用
     引用它會在執行測試之前呼叫它:test模組或類可以使用pytest.mark.usefixtures(fixturename標記。
     測試功能可以直接使用fixture名稱作為輸入引數,在這種情況下,夾具例項從fixture返回功能將被注入。
 
    :arg scope: scope 有四個級別引數 "function" (預設), "class", "module" or "session".
 
    :arg params: 一個可選的引數列表,它將導致多個引數呼叫fixture功能和所有測試使用它
 
    :arg autouse:  如果為True,則為所有測試啟用fixture func 可以看到它。 如果為False(預設值)則顯式需要參考來啟用fixture
 
    :arg ids: 每個字串id的列表,每個字串對應於params 這樣他們就是測試ID的一部分。 如果沒有提供ID它們將從params自動生成
 
    :arg name:   fixture的名稱。 這預設為裝飾函式的名稱。 如果fixture在定義它的同一模組中使用,夾具的功能名稱將被請求夾具的功能arg遮蔽; 解決這個問題的一種方法是將裝飾函式命名
                       “fixture_ <fixturename>”然後使用”@ pytest.fixture(name ='<fixturename>')“”。

注意:fixture可以使用“return”或“yield”為測試函式提供它們的值宣告。

使用“yield”時,執行“yield”語句後的程式碼塊,無論測試結果如何,都必須精確地生成一次。

fixture引數傳入(scope="function")

1.實現場景:用例1需要先登入,用例2不需要登入,用例3需要登入

# conding:utf-8
#test_f1.py
import pytest
@pytest.fixture()
def login():
    print("輸入賬號,密碼先登入")
def test_1(login):
    print("用例1:登入之後,操作")
def test_2():
    print("用例2:不登入,直接操作")
def test_3(login):
    print("用例3:登入之後,操作")
if __name__=="__main__":
    pytest.main(["-s","test_f1.py"]) 

執行結果

============================= test session starts =============================
platform win32 -- Python 3.7.0, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: E:\study\python2020collected 3 items
 
test_f1.py 輸入賬號,密碼先登入
.用例1:登入之後,操作
.用例2:不登入,直接操作
輸入賬號,密碼先登入
.用例3:登入之後,操作
                                                           [100%]
 
============================== 3 passed in 0.01s ==============================

2.如果@pytest.fixture()裡面沒有引數,那麼預設scope="function",也就是此時的級別的function,針對函式有效。

conftest.py配置

1.上面一個案例是在同一個.py檔案中,多個用例呼叫一個登陸功能,如果有多個.py的檔案都需要呼叫這個登陸功能的話,那就不能把登陸寫到用例裡面去了。

此時應該需要有一個配置檔案,單獨管理一些預置的操作場景,Pytest裡面預設讀取conftest.py裡面的配置

conftest.py配置需要注意以下點:

  ◆conftest.py配置指令碼名稱是固定的,不能改名稱

  ◆conftest.py與執行的用例要在同一個package下(包名無要求),並且有__init__.py檔案

  ◆不需要import 匯入conftest.py,pytest用例會自動查詢

2.參考程式碼:

# coding:utf-8
#test_f1.py
import pytest
def test_1(login):
    print("用例1:登入之後,操作1")
def test_2():
    print("用例2:不登入,直接操作2")
def test_3(login):
    print("用例3:登入之後,操作3")
if __name__=="__main__":
    pytest.main(["-s","test_f1.py"])

執行結果:

fix0729\test_f1.py 輸入賬號,密碼,登入
.用例1:登入之後,操作1
.用例2:不登入,直接操作2
輸入賬號,密碼,登入
.用例3:登入之後,操作3
# coding:utf-8
#test_f2.py
import pytest
def test_t1(login):
    print("登入後操作,t1")
def test_t2():
    print("不登入,操作t2")
def test_t3():
    print("不登入,操作t3")
if __name__=="__main__":
    pytest.main(["-s","test_f2.py"]) 

執行結果:

3.單獨執行test_f1.py 和test_f2.py都能呼叫到login()方法,這樣就能實現一些公共的操作可以單獨拿出來了