pytestのパラメータ化を使用して、1つのテストケースが失敗した場合に残りのテストをスキップするにはどうすればよいですか?

アラン-フェイ

私は次のpytest.mark.parametrizeように、ますます長くなる入力をかなり遅いテスト関数にフィードするために使用しています。

@pytest.mark.parametrize('data', [
    b'ab',
    b'xyz'*1000,
    b'12345'*1024**2,
    ... # etc
])
def test_compression(data):
    ... # compress the data
    ... # decompress the data
    assert decompressed_data == data

大量のデータの圧縮には時間がかかるため、失敗した後は残りのテストをすべてスキップしたいと思います。例えば、テストは、入力に失敗した場合b'ab'(最初のもの)、b'xyz'*1000およびb'12345'*1024**2、他のすべてのparametrizationsは(実行されず又はXFAIL)スキップされるべきです。

私は次のように個々のパラメータ化にマークを付けることが可能であることを知っています:

@pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8),
    ("2+4", 6),
    pytest.param("6*9", 42, marks=pytest.mark.xfail),
])

しかし、前のテストケースのステータスに応じて、これらのマークを条件付きで適用する方法がわかりませんこれを行う方法はありますか?

ホースシュー

マークはテストが実行される前に評価されるためskipif、他のテスト結果に依存するある種の宣言型マーク(のようなを渡す方法はありませんただし、フックにカスタムテストスキップロジックを適用することはできます。インクリメンタルテストの変更-pytestドキュメントからのテストステップレシピ

# conftest.py
import pytest

def pytest_sessionstart(session):
    session.failednames = set()

def pytest_runtest_makereport(item, call):
    if call.excinfo is not None:
        item.session.failednames.add(item.originalname)

def pytest_runtest_setup(item):
    if item.originalname in item.session.failednames:
        pytest.skip("previous test failed (%s)" % item.name)  # or use pytest.xfail like in the other answer

テスト例

@pytest.mark.parametrize('i', range(10))
def test_spam(i):
    assert i != 3

収量:

=================================== test session starts ===================================
collected 10 items

test_spam.py::test_spam[0] PASSED
test_spam.py::test_spam[1] PASSED
test_spam.py::test_spam[2] PASSED
test_spam.py::test_spam[3] FAILED
test_spam.py::test_spam[4] SKIPPED
test_spam.py::test_spam[5] SKIPPED
test_spam.py::test_spam[6] SKIPPED
test_spam.py::test_spam[7] SKIPPED
test_spam.py::test_spam[8] SKIPPED
test_spam.py::test_spam[9] SKIPPED

========================================= FAILURES ========================================
_______________________________________ test_spam[3] ______________________________________

i = 3

    @pytest.mark.parametrize('i', range(10))
    def test_spam(i):
>       assert i != 3
E       assert 3 != 3

test_spam.py:5: AssertionError
====================== 1 failed, 3 passed, 6 skipped in 0.06 seconds ======================

編集:カスタムマーカーの操作

def pytest_runtest_makereport(item, call):
    markers = {marker.name for marker in item.iter_markers()}
    if call.excinfo is not None and 'skiprest' in markers:
        item.session.failednames.add(item.originalname)

def pytest_runtest_setup(item):
    markers = {marker.name for marker in item.iter_markers()}
    if item.originalname in item.session.failednames and 'skiprest' in markers:
        pytest.skip(item.name)

使用法:

@pytest.mark.skiprest
@pytest.mark.parametrize('somearg', ['a', 'b', 'c'])
def test_marked(somearg):
    ...

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ