Lightweight test report visualization. Zero JDK, single HTML, offline ready.
Project description
LiteReport
Lightweight test report visualization tool. Zero JDK, single HTML file, offline ready.
An alternative to Allure for teams that want beautiful test reports without Java dependencies.
En
Features
- Self-contained HTML — Single file, no server needed, works offline
- Multiple input formats — Native JSON, JUnit XML, or pytest plugin
- Dark / Light themes — Runtime toggle, remembers preference
- Bilingual — English and Chinese (zh/en)
- History tracking — Browse previous test runs from within the report
- Expandable suites — Click any suite row to see individual test cases
- Search & filter — Full-text search across test names and descriptions
- Duration analysis — Top slowest tests with charts
- YAML config — Customize title, theme, language, output path
- pytest plugin —
pytest --litereportgenerates reports automatically - Web UI screenshots — Capture step-by-step screenshots in web tests, embedded as base64 in reports
- Screenshot tree view — Collapsible tree structure showing each step with labeled screenshots
Installation
pip install litereport
For pytest plugin support:
pip install litereport[pytest]
Quick Start
From JSON data
litereport generate report_data.json
From JUnit XML
litereport generate junit-results.xml
With pytest
pytest --litereport
The report is generated at ./reports/report.html by default.
CLI Reference
litereport generate <SOURCE> [OPTIONS]
Options:
-o, --output TEXT Output HTML path
-c, --config TEXT Config file path
--format [json|junit] Force input format (auto-detected by default)
--with-history Include history navigation in report
litereport init Create a litereport.yaml config file
litereport history list List historical reports
litereport history clean Remove old history (--keep N)
Examples
# Generate with custom output path
litereport generate results.json -o ./docs/test-report.html
# Use a config file
litereport generate results.xml -c litereport.yaml
# Generate with history navigation
litereport generate results.json --with-history
# Initialize config
litereport init
Configuration
Create a litereport.yaml in your project root (or run litereport init):
report:
title: "My Test Report"
# logo: "./assets/logo.png" # Optional, base64-embedded into HTML
theme: "light" # light | dark
lang: "en" # en | zh
history:
enabled: true
max_entries: 30
output:
dir: "./reports"
filename: "report.html"
environment:
project: "MyProject"
team: "QA"
Config priority
- CLI arguments (highest)
litereport.yaml(project root)~/.litereport/config.yaml(global)- Built-in defaults (lowest)
pytest Plugin
Enable with the --litereport flag:
pytest --litereport
pytest --litereport --litereport-config=litereport.yaml
pytest --litereport --litereport-title="Nightly Build"
The plugin automatically:
- Collects test results, docstrings, and markers
- Generates the HTML report on session finish
- Saves history snapshots for navigation
JSON Format
LiteReport uses a simple JSON schema:
{
"title": "My Test Report",
"timestamp": "2026-05-13T10:00:00",
"duration": 12.5,
"environment": {
"python": "3.11",
"platform": "Linux"
},
"results": [
{
"name": "test_login",
"nodeid": "tests/test_auth.py::test_login",
"suite": "test_auth",
"outcome": "passed",
"duration": 1.2,
"description": "Verify user login",
"markers": ["smoke"],
"error_message": "",
"error_traceback": "",
"stdout": "",
"properties": {}
}
]
}
Supported outcome values
passed | failed | skipped | error | xfailed | xpassed
Python API
from litereport import ReportData, TestResult, ReportGenerator, LiteReportConfig
# Build data
data = ReportData(
title="API Test Report",
timestamp="2026-05-13 10:00:00",
duration=25.0,
environment={"python": "3.11", "os": "Linux"},
results=[
TestResult(name="test_get_users", suite="test_api", outcome="passed", duration=0.5),
TestResult(name="test_create_user", suite="test_api", outcome="failed", duration=1.2,
error_message="404 Not Found"),
],
)
# Generate
config = LiteReportConfig(theme="dark", lang="zh")
gen = ReportGenerator(config)
gen.generate(data, "reports/report.html")
Web UI Testing with Screenshots
LiteReport supports capturing step-by-step screenshots in web UI tests (e.g. with Playwright) and embedding them directly into the HTML report.
Setup
pip install playwright pytest litereport
playwright install chromium
Screenshot API
In your conftest.py, define a screenshot() helper:
import base64
def screenshot(page, request, label=""):
"""Capture a step screenshot and attach to test report."""
b64 = base64.b64encode(page.screenshot(full_page=True)).decode("utf-8")
data_uri = f"data:image/png;base64,{b64}"
request.node.user_properties.append(("screenshot", {"label": label, "data": data_uri}))
Usage in Tests
from conftest import screenshot
class TestLoginPage:
def test_login_flow(self, page, base_url, request):
"""Complete login flow with step screenshots"""
page.goto(f"{base_url}/login")
screenshot(page, request, "1. Open login page")
page.fill("input[name='username']", "admin")
page.fill("input[type='password']", "123456")
screenshot(page, request, "2. Fill credentials")
page.click("button[type='submit']")
page.wait_for_timeout(1000)
screenshot(page, request, "3. After submit")
Auto-screenshot on Failure
Add to conftest.py for automatic failure screenshots:
import pytest
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
setattr(item, f"rep_{rep.when}", rep)
def pytest_runtest_teardown(item, nextitem):
rep = getattr(item, "rep_call", None)
if rep is None or not rep.failed:
return
page = item.funcargs.get("page")
if page is None or page.is_closed():
return
try:
b64 = base64.b64encode(page.screenshot(full_page=True)).decode("utf-8")
data_uri = f"data:image/png;base64,{b64}"
item.user_properties.append(("screenshot", {"label": "[Auto] Failure", "data": data_uri}))
except Exception:
pass
Report Display
Screenshots appear in the report as a collapsible tree:
📸 Screenshots (3)
├─ ▶ 📷 1. Open login page ← click to expand
├─ ▶ 📷 2. Fill credentials ← each step collapsed by default
└─ ▶ ⚠️ [Auto] Failure ← auto-failure marked in yellow
- All Tests tab: Click any row with screenshots to expand the step tree
- Failures tab: Screenshot tree shown below error traceback
- Modal viewer: Click any thumbnail for full-size view with arrow-key navigation
Data Format
Screenshots are stored in TestResult.properties.screenshots as a list:
{
"properties": {
"screenshots": [
{"label": "1. Open login page", "data": "data:image/png;base64,..."},
{"label": "2. Fill credentials", "data": "data:image/png;base64,..."},
{"label": "[Auto] Failure", "data": "data:image/png;base64,..."}
]
}
}
Project Structure
src/litereport/
├── models.py # TestResult, ReportData
├── config.py # YAML config loading
├── generator.py # Jinja2 HTML renderer
├── history.py # History management
├── cli.py # Click CLI
├── adapters/ # JSON + JUnit XML parsers
├── pytest_plugin/ # pytest integration
└── templates/ # Jinja2 templates
Development
git clone <repo-url>
cd litereport
pip install -e ".[dev]"
pytest
中文
项目中 litereport 的实际实现,使用方式如下:
安装
# 方式一:从 PyPI(如果已发布)
pip install litereport[pytest]
# 方式二:本地开发安装(像本项目这样)
pip install -e ../litereport[pytest]
[pytest] 会额外安装 pytest 依赖,并注册 litereport 这个 pytest 插件。
基本使用
# 最简方式 — 加 --litereport 即可
pytest --litereport
# 指定报告标题
pytest --litereport --litereport-title="我的测试报告"
# 指定配置文件
pytest --litereport --litereport-config=litereport.yaml
不加 --litereport 时插件不激活,零开销。
配置文件(可选)
在项目根目录创建 litereport.yaml:
report:
title: "API 测试报告"
theme: "light" # light | dark
lang: "zh" # zh | en
history:
enabled: true
max_entries: 30
output:
dir: "./reports"
filename: "report.html"
environment:
project: "我的项目"
team: "QA"
没有配置文件也能运行,全部使用内置默认值。
产出文件
运行后在 ./reports/ 目录(默认)生成:
| 文件 | 说明 |
|---|---|
report.html |
自包含 HTML 报告,直接浏览器打开 |
report_data.json |
测试数据 JSON,可供二次处理 |
history/ |
历史报告快照(如果 history.enabled=true) |
工作原理
litereport 通过 pyproject.toml 中的 pytest11 entry point 注册为 pytest 插件:
# litereport/pyproject.toml
[project.entry-points.pytest11]
litereport = "litereport.pytest_plugin"
pip install 后 pytest 自动发现插件。--litereport 开关控制是否激活(plugin.py:36):
def pytest_configure(config):
if config.getoption("--litereport", default=False):
plugin = LiteReportPlugin(...)
config.pluginmanager.register(plugin, "litereport_plugin")
激活后,插件通过 pytest hooks 收集每条测试结果,session 结束时自动生成报告。
本项目的实际例子
cd api-test
venv\Scripts\activate
pytest --litereport --litereport-title="基金监控系统 API 测试报告" -v
# 报告输出到 reports/report.html
Web UI 测试与截图
LiteReport 支持在 Web UI 测试中(如使用 Playwright)逐步截图,并将截图以 base64 内嵌到 HTML 报告中,报告仍然是单文件自包含可离线查看。
安装依赖
pip install playwright pytest litereport
playwright install chromium
截图 API
在 conftest.py 中定义 screenshot() 函数:
import base64
def screenshot(page, request, label=""):
"""捕获一步截图并附加到测试报告"""
b64 = base64.b64encode(page.screenshot(full_page=True)).decode("utf-8")
data_uri = f"data:image/png;base64,{b64}"
request.node.user_properties.append(("screenshot", {"label": label, "data": data_uri}))
在测试中使用
from conftest import screenshot
class TestLoginPage:
def test_login_flow(self, page, base_url, request):
"""完整登录流程多步骤截图"""
page.goto(f"{base_url}/login")
screenshot(page, request, "1. 打开登录页")
page.fill("input[name='username']", "admin")
page.fill("input[type='password']", "123456")
screenshot(page, request, "2. 填写用户名密码")
page.click("button[type='submit']")
page.wait_for_timeout(1000)
screenshot(page, request, "3. 点击登录按钮")
失败自动截图
在 conftest.py 中添加 hook,测试失败时自动截图:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
setattr(item, f"rep_{rep.when}", rep)
def pytest_runtest_teardown(item, nextitem):
rep = getattr(item, "rep_call", None)
if rep is None or not rep.failed:
return
page = item.funcargs.get("page")
if page is None or page.is_closed():
return
try:
b64 = base64.b64encode(page.screenshot(full_page=True)).decode("utf-8")
data_uri = f"data:image/png;base64,{b64}"
item.user_properties.append(("screenshot", {"label": "[Auto] Failure", "data": data_uri}))
except Exception:
pass
报告展示效果
截图在报告中以树状折叠结构展示:
📸 截图 (3)
├─ ▶ 📷 1. 打开登录页 ← 点击展开查看截图
├─ ▶ 📷 2. 填写用户名密码 ← 默认折叠
└─ ▶ ⚠️ [Auto] Failure ← 自动失败截图黄色标记
- 全部用例标签页:点击有截图的行展开步骤树
- 失败详情标签页:错误 traceback 下方显示截图树
- 模态框大图:点击缩略图弹出大图,支持左右箭头翻页
- 自动失败截图:
[Auto]前缀 + 警告图标 + 黄色标记,一眼区分截图原因
运行方式
cd web-test
pip install -r requirements.txt
playwright install chromium
pytest --litereport
# 报告输出到 reports/report.html
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file litereport-1.0.2.tar.gz.
File metadata
- Download URL: litereport-1.0.2.tar.gz
- Upload date:
- Size: 38.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0rc3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40b98f693456082d517dc9b887e83dce76d23dc247dc139f1fe7fa87afda8e34
|
|
| MD5 |
1f894222b49a11575e1d41cda2759d79
|
|
| BLAKE2b-256 |
71699865463b53751afdfe1ecdf3e542a5416e1e92d9d88adfe72a6a923571b2
|
File details
Details for the file litereport-1.0.2-py3-none-any.whl.
File metadata
- Download URL: litereport-1.0.2-py3-none-any.whl
- Upload date:
- Size: 33.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0rc3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db0b8feb511234c0283e227afa9760c6a704e24621d6d9947cf158c90de73c98
|
|
| MD5 |
f926e442d3f8604d71dc1433c753c5cb
|
|
| BLAKE2b-256 |
a9749f8b0d0e8c036f7a71cba2ef07d22b45cf91005155227d69c684cf7c10e1
|