如何在 py.test 运行结束后获取 TestReports 列表?

5
我希望在所有测试结束时获得所有测试的列表(例如以py.test TestReport的形式)。我知道pytest_runtest_makereport可以做类似的事情,但仅适用于单个测试。但是我想在conftest.py中实现一个钩子或其他东西来处理整个测试列表,在py.test应用程序终止之前。是否有方法可以做到这一点?

你是想在终端上打印出所有测试的列表,还是将其输出到一个XML文件中? - Rafael
不需要。我想要一个像pytest_runtest_makereport这样的方法来处理结果列表。我可能想要打印出一些东西,但是以我需要的方式。 - Alex
1个回答

6

这里有一个例子可以帮助你。文件的结构如下:

/example:
   __init__.py  # empty file
   /test_pack_1
      __init__.py # empty file
      conftest.py # pytest hooks
      test_my.py  # a few tests for demonstration

test_my.py中有2个测试:

def test_one():
    assert 1 == 1
    print('1==1')


def test_two():
    assert 1 == 2
    print('1!=2')

conftest.py示例:

import pytest
from _pytest.runner import TestReport
from _pytest.terminal import TerminalReporter


@pytest.hookimpl(hookwrapper=True)
def pytest_terminal_summary(terminalreporter):  # type: (TerminalReporter) -> generator
    yield
    # you can do here anything - I just print report info
    print('*' * 8 + 'HERE CUSTOM LOGIC' + '*' * 8)

    for failed in terminalreporter.stats.get('failed', []):  # type: TestReport
        print('failed! node_id:%s, duration: %s, details: %s' % (failed.nodeid,
                                                                 failed.duration,
                                                                 str(failed.longrepr)))

    for passed in terminalreporter.stats.get('passed', []):  # type: TestReport
        print('passed! node_id:%s, duration: %s, details: %s' % (passed.nodeid,
                                                                 passed.duration,
                                                                 str(passed.longrepr)))

文档中提到pytest_terminal_summary有一个exitstatus参数。

不使用任何其他选项运行测试:py.test ./example。输出示例:

example/test_pack_1/test_my.py .F
********HERE CUSTOM LOGIC********
failed! node_id:test_pack_1/test_my.py::test_two, duration: 0.000385999679565, details: def test_two():
>       assert 1 == 2
E       assert 1 == 2

example/test_pack_1/test_my.py:7: AssertionError
passed! node_id:test_pack_1/test_my.py::test_one, duration: 0.00019907951355, details: None

=================================== FAILURES ===================================
___________________________________ test_two ___________________________________

    def test_two():
>       assert 1 == 2
E       assert 1 == 2

example/test_pack_1/test_my.py:7: AssertionError
====================== 1 failed, 1 passed in 0.01 seconds ======================

希望这能帮到您。
注意!在运行测试之前,请确保删除.pyc文件。

@Alex,我很高兴能帮到你。祝你好运! - Danila Ganchar
一个问题:我为什么需要那个“yield”语句?我不能把它删除吗? - Alex
1
@Alex 不对。pytest 希望 hook 返回生成器。 - Danila Ganchar
有没有办法在 pytest 摘要打印后再打印内容?谢谢。 - CodeCollector
@CodeCollector 我不知道,需要调查。 - Danila Ganchar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接