微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

向 TestReport 对象添加新字段并在 pytest_html_results_table_html 钩子中使用它

如何解决向 TestReport 对象添加新字段并在 pytest_html_results_table_html 钩子中使用它

我想获取有关在测试 call 阶段引发的异常的信息,并将它们添加到使用 pytest-html 插件创建的报告中。所以我为 hookwrapper 创建了 pytest_runtest_makereport

@hookimpl(hookwrapper=True)
def pytest_runtest_makereport(call):
    outcome = yield
    result = outcome.get_result()
    errors = getattr(result,"errors",[])
    if result.when == "call":
        if result.Failed:
            if error := call.excinfo:
                errors.append(error.typename)
                result.errors = errors
        else:
            logger.info("PASSED")

要将此信息添加到测试报告中,我正在使用:

def pytest_html_results_table_html(report,data):
    del data[:]
    if errors := getattr(report,[]):
        data.append(html.div(",".join(errors),class_="Failed log"))

不幸的是,在 pytest_html_results_table_html 中,报告实例中没有错误字段。如果我将 result.errors = errors 添加到拆卸阶段,字段会出现在报表对象中,但它有空列表。 我知道有一个 extra 字段,但 pytest-html 将其直接添加到报告中。我想在添加这些值之前对其进行处理。

那么我在这里错过了什么?如何将此值从 pytest_runtest_makereport 传递到 pytest_html_results_table_html

我正在使用的示例测试类:

from logging import getLogger

from pytest import fixture

logger = getLogger()


class TestvarIoUsOutputs:
    @fixture()
    def setup(self):
        logger.info("Run setup")
        raise RuntimeError("Error raised during setup")

    @fixture()
    def teardown(self):
        logger.info("Run setup")
        yield
        logger.info("Run teardown")
        raise RuntimeError("Error raised during teardown")

    def test_pass(self):
        logger.info("Run test")
        assert True

    def test_fail(self):
        logger.info("Run test")
        assert False,"Assert False"

    def test_raise_error(self):
        logger.info("Run test")
        raise RuntimeError("Error raised during test run")

    def test_setup_raise_error(self,setup):
        logger.info("Run test")
        assert True

    def test_teardown_raise_error(self,teardown):
        logger.info("Run test")
        assert True

    def test_teardown_raise_error_and_test_fails(self,teardown):
        logger.info("Run test")
        assert False,"Assert False but teardown should also fail"

解决方法

因为 pytest-html 目前是这样实现的:对于每个测试用例,它将获取 teardown 报告并从 callsetup 报告中复制选定的字段。当然,自定义字段会被简单地忽略(废话!)。因此,您必须拦截 pytest 报告的这种后处理,并确保您的自定义字段出现在 teardown 报告中。放入 conftest.py 的示例:

@pytest.hookimpl(tryfirst=True)  # run our hookimpl before pytest-html does its own postprocessing
def pytest_sessionfinish(session):
    html_report = getattr(session.config,"_html",None)
    for rep_setup,rep_call,rep_teardown in html_report.reports.values():
        # copy errors field from call report to teardown report
        rep_teardown.errors = getattr(rep_call,"errors",[])

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。