💡 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
stepcontext 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-jsonto retain them - ✅
report_test_nameFixture — override the displayed test name at runtime (useful for parameterised tests) - ✅ Async Support —
stepworks as bothasync withand anasync defdecorator
⚙️ 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 |
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
- Install the plugin:
uv add pytest-reporter-html - Enable HTML report generation by adding
--report-htmlto your pytest options - Run your tests normally with
pytest - Open
logs/test-reports/TestReport_Latest.htmlin any browser - (Optional) Use
stepto 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
🤝 Contributing
If you have a helpful pattern or improvement to suggest:
- Fork the repo
- Create a new branch
- 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!
Release files for pytest-reporter-html 2.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_reporter_html-2.4.1.tar.gz | 98.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_reporter_html-2.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.4 kB
Release files / pytest_reporter_html-2.4.1.tar.gz
| Download URL | pytest_reporter_html-2.4.1.tar.gz |
|---|---|
| Size | 98.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
01377692d0a7034e058f48caee072764a0f9b644f1196d32da276ac4eb04b156
|
|
BLAKE2b-256 checksum How to use checksums |
a10ca6fb52d8629cf27c9dca0ba763ddb9f3410a6ac77454c22748823e9f2a6e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / pytest_reporter_html-2.4.1-py3-none-any.whl
| Download URL | pytest_reporter_html-2.4.1-py3-none-any.whl |
|---|---|
| Size | 23.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef60d93f73d4c166c13cf922f3ecb8ad7fa151f6451ddd29a1e6b47de6dafb62
|
|
BLAKE2b-256 checksum How to use checksums |
c2c6d7419361febbf10f0d838c926e8b194b71d11e14b4cfb626268c2dc9dd3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|