23

我想要一份在会话结束时未能使用的所有测试的列表。

Pytest 允许您定义一个钩子pytest_sessionfinish(session, exitstatus),它在会话结束时调用,我希望在其中拥有该列表。

session是一个_pytest.main.Session具有属性items(type list) 的实例,但我找不到item该列表中的 each 是否通过失败。

  1. 如何在会话结束时检索所有失败测试的列表?
  2. 使用插件时如何完成pytest-xdist,我想在主进程中获取该列表。使用这个插件, master 中session甚至没有items属性:

    def pytest_sessionfinish(session, exitstatus):
        if os.environ.get("PYTEST_XDIST_WORKER", "master") == "master":
             print(hasattr(session, "items"))  # False
    
4

7 回答 7

35

运行 pytest 以-rf使其在最后打印失败测试的列表。

来自py.test --help

  -r chars              show extra test summary info as specified by chars
                        (f)ailed, (E)error, (s)skipped, (x)failed, (X)passed,
                        (p)passed, (P)passed with output, (a)all except pP.
                        Warnings are displayed at all times except when
                        --disable-warnings is set

这是你得到的:

$ py.test -rf
================= test session starts =================
platform darwin -- Python 3.7.2, pytest-4.3.1, py-1.6.0, pluggy-0.7.1
[...]
=============== short test summary info ===============
FAILED test_foo.py::test_foo_is_flar
FAILED test_spam.py::test_spam_is_mostly_pork
FAILED test_eggs.py::test_eggs_are_also_spam
=== 3 failed, 222 passed, 8 warnings in 12.52 seconds ==
于 2019-03-26T23:12:15.913 回答
4

--result-log已弃用。您可以改为-v在运行时输出测试用例名称。如果将其通过管道传输到文件中,则可以对其进行查询。因此,如果您从脚本运行测试,您可以执行以下操作:

pytest -v | tee log.txt
grep -E '::.*(FAILURE|ERROR)' log.txt
于 2019-03-22T04:31:18.497 回答
4

您可以使用命令行选项--result-log

test_dummy.py:

def test_dummy_success():
    return


def test_dummy_fail():
    raise Exception('Dummy fail')

命令行:

$ py.test --result-log=test_result.txt

test_result.txt 的内容

. test_dummy.py::test_dummy_success
F test_dummy.py::test_dummy_fail
 def test_dummy_fail():
 >       raise Exception('Dummy fail')
 E       Exception: Dummy fail

 test_dummy.py:6: Exception

只需在第一列中搜索“F”,然后是 [file]::[test]

于 2018-01-03T04:19:02.077 回答
4

如果您想要测试结果,可以使用 hook runtest_makereport

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    outcome = yield
    rep = outcome.get_result()
    if rep.when == 'call' and rep.failed:
        mode = 'a' if os.path.exists('failures') else 'w'
        try:  # Just to not crash py.test reporting
          pass  # the test 'item' failed
        except Exception as e:
            pass
于 2018-01-03T04:28:13.367 回答
3

我想要一份关于失败的测试和参数化变化的简明报告,所以pytest_terminal_summaryconftest.py

def pytest_terminal_summary(terminalreporter, exitstatus, config):
    terminalreporter.section('Failed tests')
    failures = [report.nodeid.split('::')[-1]
                for report in terminalreporter.stats.get('failed', [])]
    terminalreporter.write('\n'.join(failures) + '\n')

如果您检查terminalreporter._session.items,您可以将更多信息添加到报告中,这正是我想要的。

于 2019-06-25T21:29:22.980 回答
1

您可以获取仅失败测试的详细信息,并使用以下命令将日志保存到文件中。日志还包含每个测试的跟踪。

py.test -rf tests/ | tee logs.txt
于 2021-01-29T15:47:26.173 回答
-1

我来访问这个问题,试图找出session实例的内部数据结构。

遍历session.items您可以检查rep_call.outcome测试结果的字符串表示形式。

def pytest_sessionfinish(session, exitstatus):
    for item in session.items:
        print('{} {}'.format(item.name, item.rep_call.outcome))

使用简单的测试用例,您会得到这个

test_positive passed
test_negative failed
于 2020-09-08T09:53:28.063 回答