首頁 > 軟體

pytest解讀fixture有效性及跨檔案共用fixtures

2022-06-01 14:01:22

fixture有效性及跨檔案共用fixtures

一、fixture有效性

fixture有效性,說白了就是fixture函數只有在它定義的使用範圍內,才可以被請求到。比如,在類裡面定義了一個fixture,那麼就只能是這個類中的測試函數才可以請求。但是,如果一個fixture定義的範圍是整個模組,那麼這個模組下的每個測試函數都可以去請求。

這裡還有另一個影響fixture有效性的引數autouse=True,預設為False,等於True的話會在其他fixture之前先執行該fixture,後面有需要另起一篇,這裡簡短帶過。

另外,一個fixture函數還可以請求任何其他的fixture函數。不管被請求的那個fixture函數在哪裡定義,只要測試函數請求了它們,fixture函數就可以。

看範例程式碼(為了更直觀的看效果,在官方程式碼基礎上我加了幾個fixture函數的print):

#  content of test_module1.py 
import pytest
@pytest.fixture
def order():
    print("n執行fixture函數-order")
    return []
@pytest.fixture
def outer(order, inner):
    print("執行fixture函數-outer")
    order.append("outer")
class TestOne:
    @pytest.fixture
    def inner(self, order):
        print("執行TestOne下的fixture-inner")
        order.append("one")
    def test_order(self, order, outer):
        assert order == ["one", "outer"]
class TestTwo:
    @pytest.fixture
    def inner(self, order):
        print("執行TestTwo下的fixture-inner")
        order.append("two")
    def test_order(self, order, outer):
        assert order == ["two", "outer"]

注意:

  • 這裡有一個fixture函數outer在測試類的外部
  • 另外還有2個名字都叫inner的fixture函數,分別在測試類TestOneTestTwo中。
  • 在外部的fixture函數outer中,又請求了內部的fixture函數inner

現在我只執行類TestOne,看執行結果:

test_module1.py 
執行fixture函數-order
執行TestOne下的fixture-inner
執行fixture函數-outer
.                                                        [100%]
============================== 1 passed in 0.01s ==============================
Process finished with exit code 0

說明測試函數裡的斷言通過。測試函數執行的時候,外部outer請求的innerTestOne下的。雖然TestOne類下的inner,只能作用於TestOne下的測試函數。但是,由於測試函數請求了外部的outer,所以,外部的outer也就可以請到內部的inner

官方還給出一個示意圖,可以結合著上述的思路,理解一下。

注意,fixture定義的範圍與它將被範例化的順序無關:範例化順序由呼叫邏輯強制執行

可以參考 https://www.jb51.net/article/250148.htm

二、跨檔案共用fixtures

如果你把fixture函數放到conftest.py檔案中,那麼在這個檔案所在的整個目錄下,都可以直接請求裡面的fixture,不需要匯入。

在實際場景中,我們的測試目錄或者包可能有多層的巢狀,這種情況下,每個目錄都可以有一個自己的conftest檔案。比如,像這樣:

各層級裡的內容是這樣的:

tests/
    __init__.py
    conftest.py
        # content of tests/conftest.py
        import pytest
        @pytest.fixture
        def order():
            return []
        @pytest.fixture
        def top(order, innermost):
            order.append("top")
    test_top.py
        # content of tests/test_top.py
        import pytest
        @pytest.fixture
        def innermost(order):
            order.append("innermost top")
        def test_order(order, top):
            assert order == ["innermost top", "top"]
    subpackage/
        __init__.py
        conftest.py
            # content of tests/subpackage/conftest.py
            import pytest
            @pytest.fixture
            def mid(order):
                order.append("mid subpackage")
        test_subpackage.py
            # content of tests/subpackage/test_subpackage.py
            import pytest
            @pytest.fixture
            def innermost(order, mid):
                order.append("innermost subpackage")
            def test_order(order, top):
                assert order == ["mid subpackage", "innermost subpackage", "top"]

同樣的,這裡也有一張作用域邊界圖幫助理解。

知識點:

  • 頂層下的conftest裡的order和top對當前層和下層級的所有可用(一個圈就對應各自的作用域)。
  • 測試函數只可以向上層級搜尋可用的fixture函數(出圈),但是出圈查詢的過程中,不能再進到別的圈子向下查詢。所以,tests/subpackage/test_subpackage.py::test_order可以找到定義在tests/subpackage/test_subpackage.py裡的innermost。但是,另一個定義在tests/test_top.py中,名字也叫innermost的fixture,對test_order來說就不可用了。

其實對於上述,按照我的白話來說,想用conftest裡的fixture函數,你只能用同層級或者上層級的。但是上級裡的其他兄弟目錄或者包,以及他們的下層級的conftest,你是不能用的。

但是讀了官方檔案,我覺得官方的那個圈子描述挺不錯的,更嚴謹。

以上就是pytest解讀fixture有效性及跨檔案共用fixtures的詳細內容,更多關於 pytest解讀fixture fixtures的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com