pytest 核心功能-重新運(yùn)行失敗的測(cè)試并在測(cè)試運(yùn)行之間保持狀態(tài)

2022-03-21 11:28 更新

用法

該插件提供了兩個(gè)命令行選項(xiàng)來(lái)重新運(yùn)行上次 pytest 調(diào)用的失?。?/p>

  • ?--lf?, ?--last-failed? - 只重新運(yùn)行失敗。
  • ?--ff?, ?--failed-first? - 先運(yùn)行失敗,然后運(yùn)行其余測(cè)試。

對(duì)于清理(通常不需要), ?--cache-clear? 選項(xiàng)允許在測(cè)試運(yùn)行之前刪除所有跨會(huì)話緩存內(nèi)容。

其他插件可以訪問(wèn) ?config.cache? 對(duì)象以在 pytest 調(diào)用之間設(shè)置/獲取 ?json可編碼值。

只重新運(yùn)行失敗或先運(yùn)行失敗

首先,我們創(chuàng)建50個(gè)測(cè)試調(diào)用,其中只有2個(gè)失敗:

# 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")

如果你第一次運(yùn)行這個(gè),你會(huì)看到兩個(gè)失敗:

$ 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? 運(yùn)行它:

$ pytest --lf
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.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 =============================

您只運(yùn)行了上次運(yùn)行的兩個(gè)失敗的測(cè)試,而 48 個(gè)通過(guò)的測(cè)試還沒(méi)有運(yùn)行。

現(xiàn)在,如果您使用 ?--ff? 選項(xiàng)運(yùn)行,所有測(cè)試都將運(yùn)行,但之前的第一個(gè)失敗將首先執(zhí)行:

$ pytest --ff
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.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? 選項(xiàng):首先運(yùn)行新測(cè)試,然后是其余測(cè)試,在這兩種情況下,測(cè)試也按文件修改時(shí)間排序,最近的文件首先出現(xiàn)。

上次運(yùn)行中沒(méi)有測(cè)試失敗時(shí)的行為

如果在上次運(yùn)行中沒(méi)有測(cè)試失敗,或者沒(méi)有找到緩存的 lastfailed 數(shù)據(jù),則可以使用 --last-failed-no-failures 選項(xiàng)將 pytest 配置為運(yùn)行所有測(cè)試或不運(yùn)行測(cè)試,該選項(xiàng)采用以下選項(xiàng)之一 :

pytest --last-failed --last-failed-no-failures all    # run all tests (default behavior)
pytest --last-failed --last-failed-no-failures none   # run no tests and exit

新的 config.cache 對(duì)象

插件或 ?conftest.py? 支持代碼可以使用 pytest 配置對(duì)象獲取緩存值。 這是一個(gè)基本示例插件,它實(shí)現(xiàn)了一個(gè)在 pytest 調(diào)用中重用先前創(chuàng)建的狀態(tài)的?fixture?:

# content of test_caching.py
import pytest
import time


def expensive_computation():
    print("running expensive computation...")


@pytest.fixture
def mydata(request):
    val = request.config.cache.get("example/value", None)
    if val is None:
        expensive_computation()
        val = 42
        request.config.cache.set("example/value", val)
    return val


def test_function(mydata):
    assert mydata == 23

如果你是第一次運(yùn)行這個(gè)命令,你可以看到 ?print語(yǔ)句:

$ pytest -q
F                                                                    [100%]
================================= FAILURES =================================
______________________________ test_function _______________________________

mydata = 42

    def test_function(mydata):
>       assert mydata == 23
E       assert 42 == 23

test_caching.py:20: 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

如果您再次運(yùn)行它,將從緩存中檢索該值,并且不會(huì)打印任何內(nèi)容:

$ pytest -q
F                                                                    [100%]
================================= FAILURES =================================
______________________________ test_function _______________________________

mydata = 42

    def test_function(mydata):
>       assert mydata == 23
E       assert 42 == 23

test_caching.py:20: AssertionError
========================= short test summary info ==========================
FAILED test_caching.py::test_function - assert 42 == 23
1 failed in 0.12s

檢查緩存內(nèi)容

您始終可以使用 ?--cache-show? 命令行選項(xiàng)查看緩存的內(nèi)容:

$ pytest --cache-show
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.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? 采用可選參數(shù)來(lái)指定用于過(guò)濾的全局模式:

$ pytest --cache-show example/*
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.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 ===========================

清除緩存內(nèi)容

您可以通過(guò)添加 ?--cache-clear? 選項(xiàng)來(lái)指示 pytest 清除所有緩存文件和值,如下所示:

pytest --cache-clear

對(duì)于來(lái)自持續(xù)集成服務(wù)器的調(diào)用,建議這樣做,因?yàn)楦綦x和正確性比速度更重要。

Stepwise

作為 ?--lf -x? 的替代方案,特別是對(duì)于您預(yù)計(jì)大部分測(cè)試套件將失敗的情況,?--sw?, ?--stepwise? 允許您一次修復(fù)一個(gè)。 測(cè)試套件將一直運(yùn)行到第一次失敗,然后停止。 在下一次調(diào)用時(shí),測(cè)試將從上一個(gè)失敗的測(cè)試?yán)^續(xù),然后運(yùn)行直到下一個(gè)失敗的測(cè)試。 您可以使用 ?--stepwise-skip? 選項(xiàng)忽略一個(gè)失敗的測(cè)試并在第二個(gè)失敗的測(cè)試上停止測(cè)試執(zhí)行。 如果您陷入失敗的測(cè)試并且只想在以后忽略它,這很有用。 提供 ?--stepwise-skip? 也將隱式啟用 ?--stepwise?


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)