xUnit style 結構的 fixture用於初始化測試函式, pytest fixture是對傳統的 xUnit 架構的setup/teardown功能的改進。pytest fixture為測試準備一個良好的測試環境,測試函式使用的每個 fixture通常有一個引數(以 fixture 命名),測試函式通過引數訪問它們。本文將介紹pytest fixture的一些基本用法。
@pytest.fixture
import pytest
@pytest.fixture()
def login():
print("登入")
return 8
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self, login):
print("\n開始執行測試用例2")
print(login)
assert 2 + login == 10
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
test_case2需要呼叫login方法(或者獲取login的返回值),pytest 將會尋找並呼叫@pytest.fixture
標記的login() 方法。
結果:
PASSED [ 33%]
開始執行測試用例1
登入
PASSED [ 66%]
開始執行測試用例2
8
PASSED [100%]
開始執行測試用例3
共享 fixture 函式:conftest.py
在測試過程中,多個測試檔案可能都要呼叫 fixture 函式,可以將其移動到 conftest.py 檔案中。conftest.py 檔案中的 fixture 函式不需要在測試函式中匯入,可以被 pytest 自動識別,查詢順序從測試類開始,然後是測試模組,然後是 conftest.py 檔案,最後是內建外掛和第三方外掛。
conftest.py :
import pytest
@pytest.fixture()
def login():
print("登入")
return 8
測試用例:
import pytest
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self, login):
print("\n開始執行測試用例2")
print(login)
assert 2 + login == 10
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
PASSED [ 33%]
開始執行測試用例1
登入
PASSED [ 66%]
開始執行測試用例2
8
PASSED [100%]
開始執行測試用例3
yield方法
使用yield關鍵字可以實現setup/teardown的功能,在yield關鍵字之前的程式碼在case之前執行,yield之後的程式碼在case執行結束後執行
import pytest
@pytest.fixture()
def login():
print("登入")
yield
print("退出登入")
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self, login):
print("\n開始執行測試用例2")
assert 2 + 8 == 10
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
PASSED [ 33%]
開始執行測試用例1
登入
PASSED [ 66%]
開始執行測試用例2
退出登入
PASSED [100%]
開始執行測試用例3
addfinalizer方法
addfinalizer也可以實現環境的清理,實現與yield方法相同的效果,跟yield不同的是需要註冊作為終結器使用的函式。
import pytest
@pytest.fixture()
def login(request):
print("登入")
def demo_finalizer():
print("退出登入")
# 註冊demo_finalizer為終結函式
request.addfinalizer(demo_finalizer)
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self, login):
print("\n開始執行測試用例2")
assert 2 + 8 == 10
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
PASSED [ 33%]
開始執行測試用例1
登入
PASSED [ 66%]
開始執行測試用例2
退出登入
PASSED [100%]
開始執行測試用例3
fixture 作用範圍:Scope
fixture 作用範圍可以為module、class、session和function,預設作用域為function。
- function:每一個函式或方法都會呼叫
- class:每一個類呼叫一次
- module:每一個.py檔案呼叫一次
- session:是多個檔案呼叫一次
scope="function"
import pytest
@pytest.fixture(scope="function")
def login():
print("登入...")
class Test_Demo():
def test_case1(self, login):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self, login):
print("\n開始執行測試用例2")
assert 2 + 8 == 10
def test_case3(self, login):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
登入...
PASSED [ 33%]
開始執行測試用例1
登入...
PASSED [ 66%]
開始執行測試用例2
登入...
PASSED [100%]
開始執行測試用例3
scope="class"
一個class裡面多個用例都呼叫了此fixture,那麼只在class裡所有用例開始前執行一次
import pytest
@pytest.fixture(scope="class")
def login():
print("登入...")
結果:
登入...
PASSED [ 33%]
開始執行測試用例1
PASSED [ 66%]
開始執行測試用例2
PASSED [100%]
開始執行測試用例3
fixture自動應用
autouse引數
autouse設定為True時,自動呼叫fixture功能。由於預設作用域為function,不指定scope則每個方法都會呼叫fixture方法。
import pytest
@pytest.fixture(autouse=True)
def login():
print("登入...")
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self):
print("\n開始執行測試用例2")
assert 2 + 8 == 10
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
登入...
PASSED [ 33%]
開始執行測試用例1
登入...
PASSED [ 66%]
開始執行測試用例2
登入...
PASSED [100%]
開始執行測試用例3
@pytest.mark.usefixtures()
在測試方法上加@pytest.mark.usefixtures()
import pytest
@pytest.fixture()
def login():
print("登入...")
@pytest.mark.usefixtures("login")
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 1 + 1 == 2
def test_case2(self):
print("\n開始執行測試用例2")
assert 2 + 8 == 10
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
登入...
PASSED [ 33%]
開始執行測試用例1
登入...
PASSED [ 66%]
開始執行測試用例2
登入...
PASSED [100%]
開始執行測試用例3
fixture函式引數化
如果多條用例都需要呼叫相同引數,可以將fixture函式引數化。fixture 函式將執行每個引數值,fixture通過固定引數request傳遞。
import pytest
@pytest.fixture(scope="module", params=[
[1, 1, 2],
[2, 8, 10],
[99, 1, 100]
])
def data(request):
yield request.param
class Test_Demo():
def test_case1(self):
print("\n開始執行測試用例1")
assert 2 + 8 == 10
def test_case2(self, data):
print("\n開始執行測試用例2")
assert data[0] + data[1] == data[2]
def test_case3(self):
print("\n開始執行測試用例3")
assert 99 + 1 == 100
if __name__ == '__main__':
pytest.main()
結果:
PASSED [ 20%]
開始執行測試用例1
PASSED [ 40%]
開始執行測試用例2
PASSED [ 60%]
開始執行測試用例2
PASSED [ 80%]
開始執行測試用例2
PASSED [100%]
開始執行測試用例3
文章標題:Pytest測試框架(三):pytest fixture 用法
本文作者:hiyo
本文連結:https://www.cnblogs.com/hiyong/p/14163280.html
歡迎關注公眾號:「測試開發小記」及時接收最新技術文章!