Skip to main content

PyPI version Python Development Status Maintenance PyPI License


💡 pytest-reporter-html

A pytest plugin that automatically generates rich, interactive HTML test reports with zero-config log capture, named step tracking, exception rendering, and real-time filtering — open the file in any browser and start debugging.


📦 Installation

uv add pytest-reporter-html

🚀 Features

  • ✅ Zero-Config Log Capture — attaches to Python's root logger automatically; every logging.*() call is captured as a report event without any code changes
  • ✅ Named Steps — group events into collapsible, timed steps using the step context manager or decorator (sync and async); supports nested steps with automatic hierarchical numbering (1, 1.1, 1.2, 2, …)
  • ✅ Automatic Phase Steps — Setup, test body, and Teardown phases are created automatically for every test
  • ✅ Interactive HTML Report — real-time search, status filter (Passed/Failed), log-level filter (TRACE→ERROR), expand/collapse all, progress bar
  • ✅ Exception Rendering — full tracebacks captured and rendered as collapsible blocks; failed tests auto-expand
  • ✅ JSON + HTTP Visualisation — embedded JSON is syntax-highlighted; HTTP requests are shown with a generated cURL command and copy button
  • ✅ Automatic JSON Cleanup — intermediate per-test JSON files are deleted after the HTML is generated by default; use --keep-json to retain them
  • ✅ report_test_name Fixture — override the displayed test name at runtime (useful for parameterised tests)
  • ✅ Async Support — step works as both async with and an async def decorator

⚙️ Configuration

Enable the HTML report by adding --report-html to your pytest options:

# pytest.ini / pyproject.toml
[pytest]
addopts = --report-html

Or pass it directly on the command line:

pytest --report-html

CLI options

Option Default Description
--report-html off Generate an aggregated HTML report at session end
--keep-json off Keep intermediate per-test JSON files after HTML generation
--report-html-dir logs/test-reports Directory for the JSON/HTML output
--report-html-title Test Report Title of the HTML report

By default, the JSON files written during the run are deleted once the HTML report is produced. Pass --keep-json if you need them for other tooling:

pytest --report-html --keep-json

🛠️ How to Use

  1. Install the plugin: uv add pytest-reporter-html
  2. Enable HTML report generation by adding --report-html to your pytest options
  3. Run your tests normally with pytest
  4. Open logs/test-reports/TestReport_Latest.html in any browser
  5. (Optional) Use step to group log events into named, collapsible blocks

🚀 Quick Start

# pyproject.toml
[tool.pytest.ini_options]
addopts = "--report-html"
pytest

After the run, open the report:

logs/test-reports/TestReport_Latest.html

▶️ Usage Examples

Example 1: Named steps with logging

from custom_python_logger import get_logger
from pytest_reporter_html import step

logger = get_logger(__name__)

def test_user_lifecycle():
    with step("Create user"):
        logger.info("Creating a new user with role 'user'")

    with step("Update profile"):
        logger.info("Updating user profile to set role to 'admin'")

    with step("Verify changes"):
        logger.info("Verifying that the user's role has been updated to 'admin'")

Report output:

Test: test_user_lifecycle                                            PASSED
 ├── Step 1: Create user                                PASSED    120ms
 ├── Step 2: Update profile                             PASSED     45ms
 └── Step 3: Verify changes                             PASSED     30ms

Example 2: Nested steps

Steps can be nested to any depth. Each level gets a hierarchical number automatically (1.1, 1.2, 2.1, …).

from custom_python_logger import get_logger
from pytest_reporter_html import step

logger = get_logger(__name__)

def test_user_lifecycle():
    with step("Create user"):
        logger.info("Creating a new user with role 'user'")
        with step("Assign default role"):
            logger.info("Setting role to 'viewer'")
        with step("Send welcome email"):
            logger.info("Email dispatched")

    with step("Update profile"):
        logger.info("Updating user profile to set role to 'admin'")

    with step("Verify changes"):
        logger.info("Verifying that the user's role has been updated to 'admin'")

Report output:

Test: test_user_lifecycle                                            PASSED
 ├── Step 1: Create user                                PASSED    120ms
 │    ├── Step 1.1: Assign default role                 PASSED     30ms
 │    └── Step 1.2: Send welcome email                  PASSED     20ms
 ├── Step 2: Update profile                             PASSED     45ms
 └── Step 3: Verify changes                             PASSED     30ms

Sub-steps appear visually indented inside their parent step in the HTML report.


Example 3: step as a decorator

from custom_python_logger import get_logger
from pytest_reporter_html import step

logger = get_logger(__name__)

@step("Fetch user data")
def get_user(user_id: str) -> dict:
    logger.info(f"Fetching user {user_id}")
    return {"id": user_id, "active": True}

@step("Send notification")
async def notify(user_id: str) -> None:
    logger.info(f"Sending notification to user {user_id}")

def test_flow():
    user = get_user("u-1")   # → Step 1: Fetch user data
    assert user["active"] is True

Example 4: Failure output

When a test fails it auto-expands in the report, showing the failure message, stack trace, and all log events up to the point of failure:

from custom_python_logger import get_logger
from pytest_reporter_html import step

logger = get_logger(__name__)

def test_order_checkout():
    with step("Create order"):
        logger.info("Creating order with 3 items")

    with step("Checkout"):
        logger.info("Submitting checkout request")
        assert False, "Checkout failed — payment declined"  # ← step is marked FAILED

🧑‍💻 HTML Report Example

Open HTML Report Example


🤝 Contributing

If you have a helpful pattern or improvement to suggest:

  1. Fork the repo
  2. Create a new branch
  3. Submit a pull request

Contributions that improve report quality, add new rendering formats, or extend CI integrations are welcome.


📄 License

MIT License — see LICENSE for details.


🙏 Thanks

Thanks for exploring this repository!
Happy coding!

GitHub   PyPI   LinkedIn

GitHub   PyPI   Blog   LinkedIn

Metadata

Release files for pytest-reporter-html 2.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-reporter-html 2.5.0
File Size Uploaded Provenance Actions
pytest_reporter_html-2.5.0.tar.gz 104.0 kB Without provenance Details for pytest_reporter_html-2.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pytest-reporter-html 2.5.0
File Interpreter ABI Platform Actions
pytest_reporter_html-2.5.0-py3-none-any.whl Python 3 none any Details for pytest_reporter_html-2.5.0-py3-none-any.whl

Total release size: 129.1 kB

Release files / pytest_reporter_html-2.5.0.tar.gz

Download URL pytest_reporter_html-2.5.0.tar.gz
Size 104.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d13366d3eba27fc86abba0210a8f12b032331efd2cab3da6334d4b13d379fd37
BLAKE2b-256 checksum
How to use checksums
f5304e419ceec1b82985b8ea5f11277ca3258b90e3d033688406ff2c3bb86bf1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / pytest_reporter_html-2.5.0-py3-none-any.whl

Download URL pytest_reporter_html-2.5.0-py3-none-any.whl
Size 25.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c8f8b92fcd8e5a2e97b173a6107a0cc6fdac5832b7ec1e5bb194eb2b1c3860a5
BLAKE2b-256 checksum
How to use checksums
84c02eada72cff24211462c554a014e24ba67d3f42773c3bf3e71d266a955ff3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for pytest-reporter-html 2.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page