pytest HTML Reporter
pytest-html-reporter · v0.4.3

One file.
The whole test run.

pytest-html-reporter turns a pytest run into a single, self-contained HTML page — no server, no build step, no assets folder. Overview, analytics, per-test steps, screenshots, captured logs, coverage and a full archive of every build before this one, in light or dark.

Zero configuration One self-contained file Light & dark themes Test steps pytest-bdd Auto screenshots Attachments & API logs Captured stdout & logging Analytics & flakiness Trends across builds Build archives Coverage Deep links Named profiles Environment snapshot xdist Rerun Sharded runs, merged JUnit XML GitHub Action VS Code extension
PyPI version Downloads Coverage MIT licence
pytest_html_report.html
The generated pytest HTML report in motion: overview tiles, trend chart, per-test steps, screenshots and archives
Quickstart

Three minutes to your first report

Nothing to register, nothing to import. Add the package, run pytest, and the report is waiting in report/ — and on a local run it opens by itself.

  1. Install

    One package. It registers itself with pytest through an entry point.

  2. Run your suite

    No flags needed. Add --html-report only if you want a different path, filename or title.

  3. Open the page

    A single HTML file you can email, attach to a ticket, or publish to Pages as-is.

shell
$ pip3 install pytest-html-reporter
$ pytest tests/

# -> ./pytest_html_report.html
It opens itself On a local run the finished report is opened in your browser. On a build agent it stays quiet — CI is detected, not guessed at.
How it compares

One file, or a pipeline

Three ways to get a report out of pytest, across sixty-three things a report is asked to do. Where a tool can do something only with a flag or a line of your own code, the cell says which one.

Section Capability pytest-html pytest-html-reporter this project allure-pytest
Ease of setup The pytest run writes the finished report results first, then allure generate
A report with no flags at all needs --html=path a plain pytest run writes one needs --alluredir, then a render
Nothing to install beyond Python Allure 2 needs Java; Allure 3 needs Node.js
It opens itself when the run ends and stays quiet on a build agent through allure serve
Report portability One self-contained HTML file with --self-contained-html; otherwise an assets/ folder the report is self-contained; screenshot files may also be kept beside it Allure 3: --single-file / singleFile: true; multi-file by default
No second tool to render it the allure CLI does the rendering
Mail it, or attach it to a ticket once it is self-contained one file, always with Allure 3 single-file mode
Deep links & shareability A deep link to one test built from the node id, not the row's position a URL per test case
Copy that link from the row itself beside the failure
Dashboard UX Status counts and run duration
Search, sort and filter the results
One click for “only the failures” status checkboxes the count pills are the filter
Export the table to CSV, Excel or print five exports, from the table itself CSV export; not Excel or print
A breakdown per suite the Suites tab
Theme Light and dark themes no built-in toggle; custom CSS with --css follows the machine, remembers the choice Allure 3 has configurable themes, via --theme
Failure triage Failures grouped by the exception behind them biggest group first, tests named categories instead; Allure 2 also ships Product and Test defects, and custom rules
Copy the error, or the rerun command quoted for your shell
A cut message that says it was cut and the exports still carry the ellipsis
Screenshots Taken with no hook or fixture of your own you take and attach them a failing Selenium or Playwright test is photographed you take and attach them
A gallery of every picture the run took inline on the row a tab of its own, and a thumbnail on the row per test, as attachments
Logs Captured stdout, stderr and logging as attachments
How many lines each test produced a column, opening the output section by section
API debugging Attach request and response payloads through the extras hook four helpers through allure.attach
The curl that repeats the call, credentials blanked both bodies, both header sets
A structured request and response viewer an attachment, or code of your own an API Logs tab: headers, bodies, status, timing and the cURL not in allure-pytest; HTTP-exchange viewers come from integrations such as Axios or Fetch
Security Sensitive API values redacted for you no built-in API redaction authorization, cookies, tokens, secrets, passwords and API keys not automatic in allure-pytest; some HTTP-client integrations do redact
Step diagnostics Named, timed, nested steps step(), as a block or a decorator steps are part of its model
A tree even when you name nothing set up, body and tear down, each timed fixtures arrive as set up and tear down
The failing step carries the message and the picture
Attachments land on the step that was open a paperclip on the step
Async and concurrent steps keep their timing and nesting no step model async with step(), @step on an async def, concurrent tasks stay siblings and attachments stay with the right task its steps follow the sync and thread context
BDD & markers Gherkin scenarios with no changes to the test the scenario and its Gherkin steps, captured automatically the separate Allure pytest-bdd integration
Markers shown with the scope they came from module, class or added at runtime its own decorators instead
Analytics A stability score for the suite 0–100, charged for flipping as well as failing
Flaky tests, kept apart from always-failing from history and retries
Where the time goes tests bucketed by duration duration charts
What changed since the last build newly failing, newly fixed, new, no longer run new, fixed, regressed and malfunctioned, once history is configured
Ownership & priority Owner-based analytics who owns what: test share, mean pass rate, failing now, flaky tests and time per owner Allure 3 can group analytics by owner, but not as one roll-up panel
Severity-based failure analysis how much it matters: blocker down to trivial, plus unrated, with failing counts a built-in severity and status chart
Historical analysis History across builds reports one run archived in the page itself through the Allure toolchain
Pass-rate and coverage trends pass rate
The failure delta since the last build ▲ +3 failures, and which way it moved trend charts instead
Retention by count, by age or by date three limits, and they intersect
Test coverage A Coverage tab when pytest-cov ran ring, per-file rows, trend
Coverage measured in an earlier job Cobertura, coverage.json or a data file
xdist One report from a pytest-xdist run merged in collection order
Reruns and retries evidence survives a green retry
What each attempt failed with the Rerun count opens the trail
Multi-machine sharding Shards merged into a single build --report-shard-merge copy the result dirs together
The merge runs after the shards finish a command of its own, offline allure generate over the lot
JUnit XML Written by the same run pytest's own --junitxml --report-junit, from the same records pytest's own --junitxml
Traceability metadata written into each testcase record_property by hand owner, severity and configured TMS or issue markers become <property> elements Allure labels don't become pytest JUnit properties
Machine-readable output Machine-readable results beside the report not from pytest-html itself output.json, written for every build the raw Allure JSON result files
Traceability / TMS Issue ids turned into links --report-link-pattern --allure-link-pattern
Links of your own in the side nav --report-link
Enterprise metadata Environment and build details its environment table --environment and --build-info environment.properties
Owner / team labels no built-in owner model @pytest.mark.owner("team"), several owners on one test, and the badge can link out owner is a supported Allure label
Severity labels no built-in severity model blocker, critical, normal, minor and trivial; unrated stays unrated the same five severity levels
Extensibility / hooks A Python API for attachments and steps extras gives rich attachments and content, but no step API six functions attachments, steps and labels
Configuration Named profiles for local and CI, chosen by name --report-profile=ci, in either config file
Prints what a run resolved, and which layer decided it pytest-html-reporter config
CI integration A first-party GitHub Action publishes it and comments on the PR
A first-party VS Code extension the last run in your sidebar

Checked in September 2026 against the source of pytest-html 4.2.0 and allure-pytest 2.16.0, and the Allure Report 2 and 3 documentation. A cell that needs a flag, a helper or a particular Allure version names it; an amber mark is a yes that arrives through a separate integration.

What is in the page

Everything a failing build makes you ask

A pass/fail count tells you how much went wrong. Here is the whole of what the report tells you instead — forty-four of them, in one HTML file, with nothing to switch on.

The page itself

5

Reading a run

6

Coverage

3

Steps, Gherkin & markers

6

Reading a failure

5

How a test behaves

7

Evidence

5

History

3

Running it at scale

4
The ecosystem

Three projects, one report

The plugin writes the report. The Action publishes it from CI and comments on the pull request. The extension puts the same results in your editor sidebar.

pip package

pytest-html-reporter

The pytest plugin that generates the report.

  • Self-contained static HTML
  • Analytics across every archived build
  • Screenshots, steps, logs, coverage
GitHub Action

pytest-html-reporter-action

Run the suite, keep the history, publish the page, comment on the PR.

  • Archives that survive across runs
  • Pull-request comments and thresholds
  • Publishes straight to GitHub Pages
VS Code extension

pytest-html-reporter-vscode

The same results in the editor sidebar, one click from the code.

  • Failing tests with error snippets
  • Jump straight to the test that failed
  • Build history and flaky detection
pytest HTML Reporter

Start with the guide

Installation, every command-line flag, the Python API, the report tour, the GitHub Action and the VS Code extension — all of it documented here.