Use pytest-html’s pytest_runtest_makereport hook and report.extras to attach selected diagnostics to test results, pytest-metadata hooks to populate the Environment table, and pytest’s built-in capture for ordinary failure output. Screenshots require your test’s browser or application fixture to produce an image; pytest-html can render or link that image, but it does not take screenshots itself.
Generate an HTML report
Install pytest-html in the test environment, then run pytest with an output file:
As an Amazon Associate I earn from qualifying purchases.
pytest --html=report.html
By default, report assets such as CSS and images are stored separately. To request a single-file report, use:
pytest --html=report.html --self-contained-html
That option does not guarantee that images added as file or URL references are embedded. If a screenshot is linked as an external file, moving the report without that file can leave a broken image. Choose inline image content when portability matters, and verify the resulting report in the workflow where it will be shared. The pytest-html user guide describes the supported extras and this self-contained-report limitation.
#1 Best Overall
Attach a screenshot or selected diagnostic to a test result
pytest-html provides helpers such as pytest_html.extras.image(), text(), json(), and url(). Add their results to report.extras in a report hook when you want to attach information conditionally across tests.
import pytest
import pytest_html
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
extras = getattr(report, "extras", [])
# This example attaches artifacts only for failures or skips in the test call.
if report.when == "call" and (report.failed or report.skipped):
# Your browser or application fixture must create and expose this path.
screenshot_path = getattr(item, "screenshot_path", None)
if screenshot_path:
extras.append(
pytest_html.extras.image(screenshot_path, name="Screenshot")
)
extras.append(
pytest_html.extras.text(
"Selected diagnostic detail", name="Diagnostic detail"
)
)
report.extras = extras
The hook wrapper receives the test report after yield. The phase check matters: each test can have setup, call, and teardown reports. The example limits attachments to a failed or skipped call; if setup or teardown errors also need artifacts, adjust the condition deliberately. This is a hook pattern, not a ready-made browser integration: obtain the screenshot from your Selenium, Playwright, or other application fixture at a point when it can still capture the relevant state.
Rank #2
For content created naturally inside an individual test, the pytest-html extras fixture can append attachments without a report hook. Use the hook for cross-cutting outcome-based behavior and the fixture for test-local artifacts. The guide notes that fixture-provided extras generally appear before extras added by plugins.
For image selection, inline image content is suited to a report that should travel independently; file and URL references avoid putting the image content into the report but depend on the referenced resource remaining reachable. In particular, a self-contained report does not turn an external image reference into embedded image data.
Use pytest’s captured output for ordinary logs
A custom attachment is not needed merely to see routine failure output. pytest captures stdout, stderr, and warning-level-and-higher logs by default, and displays captured output for failed tests. Its caplog fixture provides log records and formatted log text inside a test, with records scoped by test phase. See the pytest logging guide.
Attach a separate text or json extra when you want to expose a deliberately selected application diagnostic rather than all captured output. The report hook does not automatically provide a test’s caplog value on the report object. If your project needs to transfer test-specific data to that hook, define and clean up an explicit project-specific storage mechanism; avoid assuming a fixture value is available there.
Rank #4
If your logging setup replaces the root logger configuration, it can remove the handler pytest uses for caplog. When configuring logging with dictConfig, preserve existing handlers where appropriate and check that captured logs still appear.
Add values to the Environment table
pytest-html’s Environment section is provided by pytest-metadata. Import its metadata stash key and add values in pytest_configure when they are available before the tests run:
Best Value
from pytest_metadata.plugin import metadata_key
def pytest_configure(config):
config.stash[metadata_key]["Build"] = "staging"
config.stash[metadata_key]["Python version"] = "3.x"
For a value available only at session finish, update the stash in a tryfirst=True hook:
import pytest
from pytest_metadata.plugin import metadata_key
@pytest.hookimpl(tryfirst=True)
def pytest_sessionfinish(session, exitstatus):
session.config.stash[metadata_key]["Build"] = "staging"
tryfirst=True gives the hook a best-effort chance to run before pytest-html and pytest-metadata finalize the Environment table. Metadata entries are alphabetically sorted unless the metadata is a collections.OrderedDict. The official pytest-html user guide documents both hook patterns.
Redact sensitive metadata before sharing
Use environment_table_redact_list in pytest configuration to gray out environment values matching regular expressions in the Environment table. Variable names remain visible.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →[pytest]
environment_table_redact_list = ^API_TOKEN$
.*PASSWORD.*
.*SECRET.*
This setting applies to matching values in the metadata table; it is not a general report scrubber. Inspect screenshots, attached text, logs, and HTML extras separately before distributing a report.
Use the current plural extras API
Current examples should use report.extras and the extras fixture. pytest-html deprecated the singular report.extra and extra fixture in version 4.0.0; its deprecations page says deprecations are removed in the next major version unless stated otherwise. Check the documentation for the versions installed in your project when compatibility is important.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




