首页 > 解决方案 > pytest-4.xx:如何报告 XFAILED 等 SKIPPED 测试?

问题描述

当测试失败时,打印的原因报告有关测试文件、测试类和测试用例,而跳过的测试用例仅报告测试文件和调用跳过的行。

这是一个测试示例:

#!/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 =====================

标签: pythonpython-3.xtestingautomated-testspytest

解决方案


您有两种可能的方法来实现这一目标。快速而肮脏的方式:只需重新定义_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.


推荐阅读