如何重新執行失敗的測試並在測試執行之間保持狀態¶
用法¶
此插件提供了兩個命令行選項,用於重新運行上次 pytest
調用中失敗的測試
--lf
,--last-failed
- 僅重新運行失敗的測試。--ff
,--failed-first
- 先運行失敗的測試,然後運行其餘的測試。
為了清理(通常不需要),--cache-clear
選項允許在測試運行之前移除所有跨會話快取內容。
其他插件可以訪問 config.cache 物件,以在 pytest
調用之間設定/獲取可 JSON 編碼的值。
注意
此插件預設啟用,但如果需要可以停用:請參閱 依名稱停用/取消註冊插件(此插件的內部名稱為 cacheprovider
)。
僅重新運行失敗的測試或先運行失敗的測試¶
首先,讓我們建立 50 個測試調用,其中只有 2 個失敗
# content of test_50.py
import pytest
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
pytest.fail("bad luck")
如果您是第一次運行,您將看到兩個失敗
$ pytest -q
.................F.......F........................ [100%]
================================= FAILURES =================================
_______________________________ test_num[17] _______________________________
i = 17
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
> pytest.fail("bad luck")
E Failed: bad luck
test_50.py:7: Failed
_______________________________ test_num[25] _______________________________
i = 25
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
> pytest.fail("bad luck")
E Failed: bad luck
test_50.py:7: Failed
========================= short test summary info ==========================
FAILED test_50.py::test_num[17] - Failed: bad luck
FAILED test_50.py::test_num[25] - Failed: bad luck
2 failed, 48 passed in 0.12s
如果您然後使用 --lf
運行
$ pytest --lf
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 2 items
run-last-failure: rerun previous 2 failures
test_50.py FF [100%]
================================= FAILURES =================================
_______________________________ test_num[17] _______________________________
i = 17
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
> pytest.fail("bad luck")
E Failed: bad luck
test_50.py:7: Failed
_______________________________ test_num[25] _______________________________
i = 25
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
> pytest.fail("bad luck")
E Failed: bad luck
test_50.py:7: Failed
========================= short test summary info ==========================
FAILED test_50.py::test_num[17] - Failed: bad luck
FAILED test_50.py::test_num[25] - Failed: bad luck
============================ 2 failed in 0.12s =============================
您只運行了上次運行中失敗的兩個測試,而 48 個通過的測試沒有運行(“取消選擇”)。
現在,如果您使用 --ff
選項運行,所有測試都將運行,但先執行先前的失敗測試(可以從 FF
和點的系列中看出)
$ pytest --ff
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 50 items
run-last-failure: rerun previous 2 failures first
test_50.py FF................................................ [100%]
================================= FAILURES =================================
_______________________________ test_num[17] _______________________________
i = 17
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
> pytest.fail("bad luck")
E Failed: bad luck
test_50.py:7: Failed
_______________________________ test_num[25] _______________________________
i = 25
@pytest.mark.parametrize("i", range(50))
def test_num(i):
if i in (17, 25):
> pytest.fail("bad luck")
E Failed: bad luck
test_50.py:7: Failed
========================= short test summary info ==========================
FAILED test_50.py::test_num[17] - Failed: bad luck
FAILED test_50.py::test_num[25] - Failed: bad luck
======================= 2 failed, 48 passed in 0.12s =======================
新的 --nf
, --new-first
選項:先運行新的測試,然後運行其餘的測試,在這兩種情況下,測試也按檔案修改時間排序,較新的檔案排在前面。
上次運行中沒有測試失敗時的行為¶
--lfnf/--last-failed-no-failures
選項控制 --last-failed
的行為。 決定在沒有先前(已知)失敗時或找不到快取的 lastfailed
資料時是否執行測試。
有兩個選項
all
:當沒有已知的測試失敗時,運行所有測試(完整的測試套件)。這是預設值。none
:當沒有已知的測試失敗時,僅發出訊息說明此情況並成功退出。
範例
pytest --last-failed --last-failed-no-failures all # runs the full test suite (default behavior)
pytest --last-failed --last-failed-no-failures none # runs no tests and exits successfully
新的 config.cache 物件¶
插件或 conftest.py 支援程式碼可以使用 pytest config
物件取得快取的值。 這是一個基本範例插件,它實作了一個 fixture,該 fixture 在 pytest 調用之間重複使用先前建立的狀態
# content of test_caching.py
import pytest
def expensive_computation():
print("running expensive computation...")
@pytest.fixture
def mydata(pytestconfig):
val = pytestconfig.cache.get("example/value", None)
if val is None:
expensive_computation()
val = 42
pytestconfig.cache.set("example/value", val)
return val
def test_function(mydata):
assert mydata == 23
如果您第一次運行此命令,您可以看到 print 語句
$ pytest -q
F [100%]
================================= FAILURES =================================
______________________________ test_function _______________________________
mydata = 42
def test_function(mydata):
> assert mydata == 23
E assert 42 == 23
test_caching.py:19: AssertionError
-------------------------- Captured stdout setup ---------------------------
running expensive computation...
========================= short test summary info ==========================
FAILED test_caching.py::test_function - assert 42 == 23
1 failed in 0.12s
如果您第二次運行它,該值將從快取中檢索,並且不會列印任何內容
$ pytest -q
F [100%]
================================= FAILURES =================================
______________________________ test_function _______________________________
mydata = 42
def test_function(mydata):
> assert mydata == 23
E assert 42 == 23
test_caching.py:19: AssertionError
========================= short test summary info ==========================
FAILED test_caching.py::test_function - assert 42 == 23
1 failed in 0.12s
有關更多詳細信息,請參閱 config.cache fixture
。
檢查快取內容¶
您始終可以使用 --cache-show
命令行選項查看快取的內容
$ pytest --cache-show
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
cachedir: /home/sweet/project/.pytest_cache
--------------------------- cache values for '*' ---------------------------
cache/lastfailed contains:
{'test_caching.py::test_function': True}
cache/nodeids contains:
['test_caching.py::test_function']
cache/stepwise contains:
[]
example/value contains:
42
========================== no tests ran in 0.12s ===========================
--cache-show
接受一個可選參數來指定用於過濾的 glob 模式
$ pytest --cache-show example/*
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
cachedir: /home/sweet/project/.pytest_cache
----------------------- cache values for 'example/*' -----------------------
example/value contains:
42
========================== no tests ran in 0.12s ===========================
清除快取內容¶
您可以指示 pytest 通過添加 --cache-clear
選項來清除所有快取檔案和值,如下所示
pytest --cache-clear
建議從持續整合伺服器進行調用時使用此選項,在這種情況下,隔離和正確性比速度更重要。
逐步執行¶
作為 --lf -x
的替代方案,特別是對於您預期大部分測試套件將失敗的情況,--sw
, --stepwise
允許您一次修復一個。 測試套件將運行到第一次失敗然後停止。 在下一次調用時,測試將從上次失敗的測試繼續,然後運行到下一個失敗的測試。 您可以使用 --stepwise-skip
選項來忽略一個失敗的測試,而是在第二個失敗的測試時停止測試執行。 如果您在一個失敗的測試中卡住並且只想忽略它直到以後,這很有用。 提供 --stepwise-skip
也會隱式啟用 --stepwise
。