2

問題が修正される前に失敗したテストケースを追加できるように、マーカーを使用して失敗するが失敗してはならないpytest.mark.xfailテストをマークするプロジェクトがいくつかあります。これらのテストをスキップしたくありません。なぜなら、私が何かを行ったために合格し始めた場合は、そのことを通知して、マーカーを削除して回帰を回避できるようにしたいからです。xfail

問題は、xfailテストが失敗するまで実際に実行されるため、失敗に至るまでのヒット行は、合格していないテストの一部であっても「カバー」としてカウントされ、実際のコードの量について誤解を招くメトリックが得られることです。動作するようにテストされています。これの最小限の例は次のとおりです。

pkg.py

def f(fail):
    if fail:
        print("This line should not be covered")
        return "wrong answer"

    return "right answer"

test_pkg.py

import pytest
from pkg import f

def test_success():
    assert f(fail=False) == "right answer"

@pytest.mark.xfail
def test_failure():
    assert f(fail=True) == "right answer"

を実行python -m pytest --cov=pkgすると、次のようになります。

platform linux -- Python 3.7.1, pytest-3.10.0, py-1.7.0, pluggy-0.8.0
rootdir: /tmp/cov, inifile:
plugins: cov-2.6.0
collected 2 items

tests/test_pkg.py .x                                            [100%]

----------- coverage: platform linux, python 3.7.1-final-0 -----------
Name     Stmts   Miss  Cover
----------------------------
pkg.py       5      0   100%

ご覧のとおり、5 行すべてがカバーされていますが、3 行目と 4 行目はxfailテスト中にヒットしただけです。

tox私が今これを処理する方法は、 のようなものを実行するようにセットアップすることですpytest -m "not xfail" --cov && pytest -m xfailが、少し面倒であることに加えて、それはxfailマークが付いたものを除外するだけです。つまり、条件付きの xfails も、条件が満たされます。

失敗したテストからのカバレッジをカウントする方法とカウントしない方法はありますcoverageか? または、条件が満たされた場合にのみ条件付きテストを無視するテストpytestからのカバレッジを無視するメカニズムで問題ありません。xfailxfail

4

1 に答える 1

2

pytest-covプラグインを使用しているので、そのno_coverマーカーを利用してください。で注釈を付けるとpytest.mark.no_cover、テストのコード カバレッジがオフになります。実装するために残っている唯一のことは、 でno_coverマークされたすべてのテストにマーカーを適用することpytest.mark.xfailです。あなたのconftest.py

import pytest

def pytest_collection_modifyitems(items):
    for item in items:
        if item.get_closest_marker('xfail'):
            item.add_marker(pytest.mark.no_cover)

サンプルを実行すると、次の結果が得られます。

$ pytest --cov=pkg -v
=================================== test session starts ===================================
platform darwin -- Python 3.7.1, pytest-3.9.1, py-1.7.0, pluggy-0.8.0
cachedir: .pytest_cache
rootdir: /Users/hoefling/projects/private/stackoverflow, inifile:
plugins: cov-2.6.0
collected 2 items

test_pkg.py::test_success PASSED                                                     [ 50%]
test_pkg.py::test_failure xfail                                                      [100%]

---------- coverage: platform darwin, python 3.7.1-final-0 -----------
Name     Stmts   Miss  Cover
----------------------------
pkg.py       5      2    60%


=========================== 1 passed, 1 xfailed in 0.04 seconds ===========================

xfail編集:マーカー内の条件の扱い

マーカーの引数には、marker.argsとを介してアクセスできmarker.kwargsます。たとえば、マーカーがある場合

@pytest.mark.xfail(sys.platform == 'win32', reason='This fails on Windows')

で引数にアクセスします

marker = item.get_closest_marker('xfail')
condition = marker.args[0]
reason = marker.kwargs['reason']

条件フラグを考慮するには、上記のフックを次のように変更できます。

def pytest_collection_modifyitems(items):
    for item in items:
        marker = item.get_closest_marker('xfail')
        if marker and (not marker.args or marker.args[0]):
            item.add_marker(pytest.mark.no_cover)
于 2018-11-07T21:47:42.237 に答える