目錄
- 4、Fixture的相互呼叫
- 5、Fixture復用
- 6、Fixture快取回傳結果
- 7、Fixture的后置處理
- (一)使用yield關鍵字實作后置
- (二)使用addfinalizer關鍵字實作后置
- (三)yield和addfinalizer的區別
4、Fixture的相互呼叫
示例:
import pytest
# 第一層fixture
@pytest.fixture()
def fixture_1():
data = "https://www.cnblogs.com/qishuaiRisen/archive/2022/08/15/fixture_1"
print("這是第一層fixture")
return data
# 第二層fixture
@pytest.fixture()
def fixture_2(fixture_1): # 在這里傳遞呼叫第一層fixture
print("這是第二層fixture")
# 第三層fixture
@pytest.fixture()
@pytest.mark.usefixtures("fixture_1") # 這種fixture相互呼叫方式不生效
def fixture_3():
print("這是第三層fixture")
# 測驗類
class TestClass:
def test_1(self, fixture_1):
print("呼叫第1層fixture,回傳值為{}".format(fixture_1))
def test_2(self, fixture_2):
print("呼叫第2層fixture,回傳值為{}".format(fixture_2))
def test_3(self, fixture_3):
print("呼叫第3層fixture")
"""
執行結果
fixture/use_fixture_each_other.py::TestClass::test_1 這是第一層fixture
呼叫第1層fixture,回傳值為fixture_1
PASSED
fixture/use_fixture_each_other.py::TestClass::test_2 這是第一層fixture
這是第二層fixture
呼叫第2層fixture,回傳值為None
PASSED
fixture/use_fixture_each_other.py::TestClass::test_3 這是第三層fixture
呼叫第3層fixture
PASSED
"""
示例說明:
- 在呼叫存在相互呼叫的
fixture時,執行順序由頂層fixture逐層向下執行(如示例test_2優先執行fixture_1再執行fixture_2) - 當呼叫存在相互呼叫的
fixture時,直接被呼叫的fixture不會將自己接收到的回傳值回傳給呼叫方(如示例test_2不會接收到由fixture_1回傳的值) - 相互呼叫
fixture時不能使用pytest.mark.usefixture裝飾器(如示例fixture_3)
5、Fixture復用
不同的測驗函式可以請求相同的fixture,每個測驗函式都會獲得該fixture的各自結果,不同的測驗函式不互相影響,這樣可以保證每個測驗函式都能得到干凈一致的資料,
示例
import pytest
@pytest.fixture()
def fixture_1():
return []
def test_1(fixture_1):
fixture_1.append(0)
print(f"結果:{fixture_1}")
def test_2(fixture_1):
fixture_1.append(9)
print(f"結果:{fixture_1}")
"""
執行結果
fixture/reuse_fixture.py::test_1 結果:[0]
PASSED
fixture/reuse_fixture.py::test_2 結果:[9]
PASSED
"""
示例說明
由上面例子可以看出,兩個測驗函式都呼叫了fixture_1,但每次呼叫回傳的結果是一樣的,并不會因為test_1中fixture_1先添加了0而影響test_2呼叫的fixture_1回傳的結果
6、Fixture快取回傳結果
在同一個測驗函式多次呼叫同一個fixture時,第一次執行該fixture函式之后,會把回傳結果快取起來,不會再次執行它們
示例:
import pytest
@pytest.fixture()
def fixture_1():
print("執行fixture_1")
return "a"
@pytest.fixture()
def fixture_2():
print("執行fixture_2")
return []
@pytest.fixture()
def fixture_append(fixture_1, fixture_2):
print("執行fixture_append")
fixture_2.append(fixture_1)
def test_fixture(fixture_append, fixture_2, fixture_1):
print("執行測驗函式")
print(fixture_2)
"""
執行結果
fixture/fixture_cache.py::test_fixture 執行fixture_1
執行fixture_2
執行fixture_append
執行測驗函式
['a']
PASSED
"""
示例說明:
由上面例子可以看出在fixture函式fixture_append中,fixture_1第一次被請求回傳字母a,fixture_2被第二次被請求回傳空串列,在測驗函式test_fixture中fixture_2第二次被請求,但回傳結果不是不是空串列,而是['a'],如果同一個fixture在同一個測驗函式中每次都去請求,那么必然回傳的是空串列,
7、Fixture的后置處理
前面的案例都是加了前置處理,相當于setup(),后置teardown()在fixture中是可以通過yield關鍵字和addfinalizer關鍵字來實作
(一)使用yield關鍵字實作后置
- 示例
import pytest
@pytest.fixture(autouse=True)
def fixture_3():
print("這是一個前置處理")
yield
print("這是一個后置處理")
def testcase_1(fixture_3):
print("這是測驗用例1")
def testcase_2(fixture_3):
print("這是測驗用例2")
"""
執行結果
fixture/use_fixture_3.py::testcase_1 這是一個前置處理
這是測驗用例1
PASSED這是一個后置處理
fixture/use_fixture_3.py::testcase_2 這是一個前置處理
這是測驗用例2
PASSED這是一個后置處理
"""
- 執行順序
在前置處理中會根據fixture函式之間的線性關系順序呼叫的,后置處理順序會反過來
import pytest
@pytest.fixture()
def fixture_1():
print("這是fixture_1")
return 1
@pytest.fixture()
def fixture_2(fixture_1):
print("這是fixture_2的【前置】")
yield 2
print("這是fixture_2的【后置】")
@pytest.fixture()
def fixture_add(fixture_1, fixture_2):
print("這是fixture_add的【前置】")
yield fixture_1 + fixture_2
print('這是fixture_add的【后置】')
def test_fixture(fixture_2, fixture_add):
print("這是測驗函式")
assert fixture_add == 3
"""
執行結果
fixture/yiled_order.py::test_fixture 這是fixture_1
這是fixture_2的【前置】
這是fixture_add的【前置】
這是測驗函式
PASSED這是fixture_add的【后置】
這是fixture_2的【后置】
"""
(二)使用addfinalizer關鍵字實作后置
- request.addfinalizer把函式變成終結器實作后置處理
import pytest
@pytest.fixture()
def fixture_1(request):
print("這是fixture_1的【前置】處理")
def addfinalizer_demo():
print("這是fixture_1的【后置】處理")
# 注冊后置處理
request.addfinalizer(addfinalizer_demo)
def test_fixture(fixture_1):
print("===這是測驗函式===")
"""
執行結果
fixture/use_addfinalizer.py::test_fixture 這是fixture_1的【前置】處理
===這是測驗函式===
PASSED這是fixture_1的【后置】處理
"""
- request.addfinalizer注冊多個終結器函式
import pytest
@pytest.fixture()
def fixture_1(request):
print("這是fixture_1的【前置】處理")
def addfinalizer_demo_1():
print("這是fixture_1的【后置】處理1")
def addfinalizer_demo_2():
print("這是fixture_2的【后置】處理2")
# 將多個后置處理函式注冊成終結函式
request.addfinalizer(addfinalizer_demo_1)
request.addfinalizer(addfinalizer_demo_2)
def test_fixture(fixture_1):
print("=====這是測驗函式=====")
"""
執行結果
fixture/use_more_addfinalizer.py::test_fixture 這是fixture_1的【前置】處理
=====這是測驗函式=====
PASSED這是fixture_2的【后置】處理2
這是fixture_1的【后置】處理1
"""
- 執行順序
由上面注冊多個終結器函式示例中可以看到,使用addfinalizer關鍵字處理后置函式的執行順序與注冊順序是反的
(三)yield和addfinalizer的區別
區別在于如果fixture中前置出現例外,yield后置不會執行,而addfinalizer后置會執行,
- 使用
yield
import pytest
@pytest.fixture()
def fixture_yield():
print("這是fixture_yield前置")
res = 21/0
yield
print("這是fixtue_yield后置")
def test_fixture(fixture_yield):
print("這是測驗函式")
"""
執行結果
yield_error.py::test_fixture ERROR [100%]這是fixture_yield前置
test setup failed
@pytest.fixture()
def fixture_yield():
print("這是fixture_yield前置")
> res = 21/0
E ZeroDivisionError: division by zero
yield_error.py:12: ZeroDivisionError
"""
- 使用
addfinalizer
import pytest
@pytest.fixture()
def fixture_1(request):
print("這是fixture_1前置")
def addfinalizer_demo():
print("這是fixture_1后置")
request.addfinalizer(addfinalizer_demo)
res = 21/0
def test_fixture(fixture_1):
print("這是測驗函式")
"""
執行結果
addfinalizer_error.py::test_fixture ERROR [100%]這是fixture_1前置
test setup failed
request = <SubRequest 'fixture_1' for <Function test_fixture>>
@pytest.fixture()
def fixture_1(request):
print("這是fixture_1前置")
def addfinalizer_demo():
print("這是fixture_1后置")
request.addfinalizer(addfinalizer_demo)
> res = 21/0
E ZeroDivisionError: division by zero
addfinalizer_error.py:16: ZeroDivisionError
這是fixture_1后置
"""
從上面yield和addfinalizer的示例中可以看出yield前置中出現例外,后置處理沒有被執行,而addfinalizer的前置中出現例外,并沒有影響后置的執行,
注意: 使用addfinalizer一定是后置函式注冊成功后出現例外才不會受影響,
參考:https://zhuanlan.zhihu.com/p/355285675
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/501896.html
標籤:其他
上一篇:Python獲取虎牙平臺主播照片, 實作顏值檢測, 進行排名
下一篇:day21--Java集合04
