pytest-4.xx: Как сообщить о пропущенных тестах, таких как XFAILED? - PullRequest
0 голосов
/ 23 апреля 2019

При выполнении теста xfailed причина, по которой печатается отчет о файле теста, классе теста и тестовом примере, в то время как пропущенный тест сообщает только файл теста и строку, где вызывается пропуск.

ВотПример теста:

#!/usr/bin/env pytest

import pytest

@pytest.mark.xfail(reason="Reason of failure")
def test_1():
    pytest.fail("This will fail here")

@pytest.mark.skip(reason="Reason of skipping")
def test_2():
    pytest.fail("This will fail here")

Это фактический результат:

pytest test_file.py -rsx
============================= test session starts =============================
platform linux -- Python 3.5.2, pytest-4.4.1, py-1.7.0, pluggy-0.9.0
rootdir: /home/ashot/questions
collected 2 items                                                             

test_file.py xs                                                         [100%]
=========================== short test summary info ===========================
SKIPPED [1] test_file.py:9: Reason of skipping
XFAIL test_file.py::test_1
  Reason of failure

==================== 1 skipped, 1 xfailed in 0.05 seconds =====================

Но я ожидал бы получить что-то вроде:

pytest test_file.py -rsx
============================= test session starts =============================
platform linux -- Python 3.5.2, pytest-4.4.1, py-1.7.0, pluggy-0.9.0
rootdir: /home/ashot/questions
collected 2 items                                                             

test_file.py xs                                                         [100%]
=========================== short test summary info ===========================
XFAIL test_file.py::test_1: Reason of failure
SKIPPED test_file.py::test_2: Reason of skipping

==================== 1 skipped, 1 xfailed in 0.05 seconds =====================

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Благодаря этому ответу Я нашел следующее решение, которое идеально подходит для меня. Я создал conftest.py файл в корне моего набора тестов со следующим содержимым:

import _pytest.skipping as s

def show_xfailed(tr, lines):
    for rep in tr.stats.get("xfailed", []):
        pos = tr.config.cwd_relative_nodeid(rep.nodeid)
        reason = rep.wasxfail
        s = "XFAIL\t%s" % pos
        if reason:
            s += ": " + str(reason)
        lines.append(s)

s.REPORTCHAR_ACTIONS["x"] = show_xfailed

def show_skipped(tr, lines):
    for rep in tr.stats.get("skipped", []):
        pos = tr.config.cwd_relative_nodeid(rep.nodeid)
        reason = rep.longrepr[-1]
        if reason.startswith("Skipped: "):
            reason = reason[9:]
        verbose_word = s._get_report_str(tr.config, report=rep)
        lines.append("%s\t%s: %s" % (verbose_word, pos, reason))

s.REPORTCHAR_ACTIONS["s"] = show_skipped
s.REPORTCHAR_ACTIONS["S"] = show_skipped

А теперь я получаю следующий вывод:

./test_file.py -rsx
============================= test session starts =============================
platform linux -- Python 3.5.2, pytest-4.4.1, py-1.7.0, pluggy-0.9.0
rootdir: /home/ashot/questions
collected 2 items                                                             

test_file.py xs                                                         [100%]
=========================== short test summary info ===========================
SKIPPED test_file.py::test_2: Reason of skipping
XFAIL   test_file.py::test_1: Reason of failure

==================== 1 skipped, 1 xfailed in 0.05 seconds =====================
0 голосов
/ 23 апреля 2019

У вас есть два возможных способа добиться этого.Быстрый и грязный способ: просто переопределите _pytest.skipping.show_xfailed в вашем test_file.py:

import _pytest

def custom_show_xfailed(terminalreporter, lines):
    xfailed = terminalreporter.stats.get("xfailed")
    if xfailed:
        for rep in xfailed:
            pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
            reason = rep.wasxfail
            s = "XFAIL %s" % (pos,)
            if reason:
                s += ": " + str(reason)
            lines.append(s)

# show_xfailed_bkp = _pytest.skipping.show_xfailed
_pytest.skipping.show_xfailed = custom_show_xfailed

... your tests

(не очень) чистый способ: создайте файл conftest.py в том же каталоге, что и ваш test_file.py,и добавьте хук:

import pytest
import _pytest

def custom_show_xfailed(terminalreporter, lines):
    xfailed = terminalreporter.stats.get("xfailed")
    if xfailed:
        for rep in xfailed:
            pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
            reason = rep.wasxfail
            s = "XFAIL %s" % (pos,)
            if reason:
                s += ": " + str(reason)
            lines.append(s)

@pytest.hookimpl(tryfirst=True)
def pytest_terminal_summary(terminalreporter):
    tr = terminalreporter
    if not tr.reportchars:
        return

    lines = []
    for char in tr.reportchars:
        if char == "x":
            custom_show_xfailed(terminalreporter, lines)
        elif char == "X":
            _pytest.skipping.show_xpassed(terminalreporter, lines)
        elif char in "fF":
            _pytest.skipping.show_simple(terminalreporter, lines, 'failed', "FAIL %s")
        elif char in "sS":
            _pytest.skipping.show_skipped(terminalreporter, lines)
        elif char == "E":
            _pytest.skipping.show_simple(terminalreporter, lines, 'error', "ERROR %s")
        elif char == 'p':
            _pytest.skipping.show_simple(terminalreporter, lines, 'passed', "PASSED %s")

    if lines:
        tr._tw.sep("=", "short test summary info")
        for line in lines:
            tr._tw.line(line)

    tr.reportchars = [] # to avoid further output

Второй метод - избыточный, потому что вам нужно переопределить целое pytest_terminal_summary.

...