pytest-dev / pytest-html

Plugin for generating HTML reports for pytest results
Other
707 stars 236 forks source link

Extras added after test execution in fixture are ignored #820

Open ascended121 opened 4 months ago

ascended121 commented 4 months ago

The docs explain that one can use the extras fixture to add content to the html report, however only some of the extras are added. In the following code:

import pytest_html

def test_extra(extras):
    extras.append(pytest_html.extras.text("before test!"))
    yield # run test
    extras.append(pytest_html.extras.text("after test!"))

only the before test part is actually added to the report. The docs don't mention anything about this behavior, so hard to tell if its a bug or not.

If this is a limitation of the framework, it would be really helpful to document it. If not, it would be really handy to fix it.

In my use case, I have a test which generates some files which I'd like to link to from the report. That has to be done after the test completes, but my links never show up in the report.

Thanks!

derteufelqwe commented 3 weeks ago

I have the same problem and developed a little workaround. For this you need the following code in your conftest.py

last_testreport = None

def pytest_runtest_logreport(report):
    """
    Grab and cache the testreport for a test, as it's required later
    """
    if report.when == 'call':
        global last_testreport
        last_testreport = report

def pytest_runtest_makereport(item, call):
    """
    There is a problem with pytest_html: Extras, which are added in the teardown stage aren't added to the report.
    This is a known bug: https://github.com/pytest-dev/pytest-html/issues/820
    The workaround is to manually insert the extra element into the testreport.
    For this to work I cache the testreport instance in the pytest_runtest_logreport hook.
    """

    if call.when == "teardown" and hasattr(item, "_report_extra"):
        extra = getattr(item, "_report_extra", [])
        for e in extra:
            last_testreport.extras.append(e)

def inject_extras_element(request, element):
    """ Injects an extra element into the testreport. This is a workaround for a known bug in pytest_html. """
    request.node._report_extra = request.node._report_extra if hasattr(request.node, '_report_extra') else []
    request.node._report_extra.append(element)

and when you want to add an extra element in a fixtures teardown, you just do

inject_extras_element(request, pytest_html.extras.text("Hello from teardown", "teardown.log"))