junit2report is a lightweight, zero-dependency Python tool that converts JUnit XML test reports into human-readable, static HTML dashboards.
Perfect for CI/CD pipelines, local debugging, or sharing test results with stakeholders.
- Simple Conversion: Turn complex XML into a clean, responsive HTML file in seconds.
- π¨ Multiple Templates: Choose from built-in themes (Dark mode, Minimal, etc.) to suit your preferences.
- CI/CD Ready: Seamlessly integrates with Jenkins, GitHub Actions, GitLab CI, and CircleCI.
- Detailed Insights: View pass/fail rates, execution times, and capture stdout/stderr logs.
- Dual Mode: Use it as a CLI tool or import it as a Python library.
Install the package via pip:
pip install junit2reportCommand Line Interface (CLI) Basic conversion (uses default template):
junit2report report.xml -o output.htmlUsing a specific template:
junit2report report.xml -o output.html --template darkSetting a custom title:
junit2report report.xml -o output.html --template legacy --title "Nightly Run"List available templates:
junit2report --list-templatesGenerating analytics reports (in addition to the main report):
junit2report report.xml -o output.html --allow-analyticsThis generates both output.html (main report) and output-analytics.html (analytics dashboard with charts and filters).
Python Library You can integrate the generator directly into your Python scripts.
from junit2report import create_report
# Convert with a specific template
create_report(
source="results.xml",
output="dashboard.html",
template="dark",
title="Nightly Run"
)
# or using a string of XML data
with open("results.xml", "r") as f:
xml_data = f.read()
html_content = create_report(xml_string=xml_data, template="minimal")The package comes with several pre-built templates to customize your report style.
| Template Name | Description | Best For |
|---|---|---|
| modern | (Default) A clean, colorful dashboard with charts and collapsible sections. | General use, stakeholder reports. |
| dark | A high-contrast dark theme version of the modern dashboard. | Late-night debugging, dark-mode lovers. |
| minimal | A text-heavy, high-density layout with no charts and only minimal inline JavaScript for basic filtering/collapsing. | Large test suites (10k+ tests), slow connections that still allow basic interactivity. |
| legacy | A simple table view similar to older Jenkins reports. | Backward compatibility. |
| analytics | Advanced analytics dashboard with multi-axis charts, performance insights, and interactive filters. | In-depth performance analysis, identifying bottlenecks. |
|
|
|
|
|
|
The generated HTML report includes:
- Summary Cards: Total tests, passed, failed, skipped, and total duration.
- Test Cases Table: Sortable list of all test cases with status indicators.
- Failure Details: Expandable sections showing stack traces and error messages.
The analytics report provides advanced insights:
- Interactive Charts: Status distribution, test count by class, execution time by class, failure distribution, and pass rate visualization.
- Performance Metrics: Detailed breakdown of test execution by class with averages and statistics.
- Error Analysis: Deduplicated error messages with frequency counts and affected tests.
- Top Tests: Slowest and fastest tests ranked by execution time.
- Filterable Sections: Use "Show top N" filters in Performance by Class and Error Analysis sections to focus on the most relevant data.
Contributions are welcome! Please feel free to submit a Pull Request.
- Clone the repository
git clone https://github.com/gorkalertxundi/junit2report.git cd junit2report
2. **Install in editable mode**
```bash
pip install -e .
This installs the package in development mode, allowing you to make changes to the source code and test them immediately without reinstalling.
- Verify the installation
junit2report --list-templates
python -c "from junit2report import get_available_templates; print(get_available_templates())"
### Running Tests
Run the test suite to ensure everything works correctly:
```bash
# Run all tests
python -m unittest discover tests
# Run tests with verbose output
python -m unittest discover tests -v
# Run a specific test
python -m unittest tests.test_parser.TestJUnitParser.test_parse_single_testsuite
All tests should pass before submitting a pull request.
- Generate a test report
junit2report sample-test-results.xml -o test-report.html
junit2report sample-test-results.xml -o dark-report.html --template dark junit2report sample-test-results.xml -o minimal-report.html --template minimal
2. **Test the Python API**
```python
from junit2report import create_report
# Test with file
create_report(source="sample-test-results.xml", output="api-test.html")
# Test with XML string
with open("sample-test-results.xml") as f:
html = create_report(xml_string=f.read(), template="dark")
print(f"Generated {len(html)} bytes of HTML")
- Test template bundling
# Build the package python -m build
tar -tzf dist/junit2report-*.tar.gz | grep templates
### Adding a New Template
1. Create your template file in `junit2report/templates/yourtemplate.html`
2. Use Jinja2 syntax with these variables:
- `{{ summary.total }}`, `{{ summary.passed }}`, `{{ summary.failed }}`, etc.
- `{{ summary.pass_rate }}` for the percentage
- `{% for test in test_cases %}` to iterate through tests
- `{{ test.name }}`, `{{ test.status }}`, `{{ test.message }}`, `{{ test.output }}`
3. Test your template: `junit2report sample-test-results.xml --template yourtemplate`
4. The template will automatically appear in `--list-templates`
### Contribution Workflow
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Make your changes and test thoroughly
4. Run the test suite to ensure nothing broke
5. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
6. Push to the branch (`git push origin feature/AmazingFeature`)
7. Open a Pull Request with a clear description of your changes
## π License
Distributed under the MIT License. See LICENSE for more information.








