Modern JSON report formatter for Behave that generates a rich, structured execution model.
Project description
behave-modern-json-report
A modern JSON report formatter for Behave that generates a rich, structured execution model for reporting, analytics, dashboards, AI, CI/CD pipelines and custom integrations.
Why?
The built-in Behave JSON formatter produces a flat, HTML-oriented structure. This project creates the canonical execution model for Behave — a schema-versioned, stable, extensible JSON format designed as an API, not as a rendering target.
It is the data foundation for:
- HTML / Markdown / Console reports
- AI-powered test analysis
- Dashboards and analytics platforms
- Historical execution comparison
- Trace viewers
- Custom integrations
Features
- Schema-versioned JSON output (
schemaVersion: "1.1.0") - Stable unique identifiers for every entity (execution, feature, scenario, step, attachment, error)
- Structured errors — type, message, traceback, location (never raw strings)
- Attachments — image, JSON, XML, HTML, PDF, video, text, binary; embedded or external
- Attachment helpers —
attach_file,attach_text,attach_json,attach_screenshot,logforenvironment.pyhooks - Step-level logs
- Gherkin backgrounds — shared background steps captured at feature and scenario level
- Rule support — Gherkin v6 / Behave 1.3.x rules tracked via
scenario.rule - Scenario outlines —
isOutlineandoutlineNamefields - Expanded statuses —
passed,failed,skipped,undefined,pending,untested,error,hook_error,cleanup_error,xfailed,xpassed - Rich statistics — pass rate, counts, duration, error count, total attachments/logs, slowest step, avg scenario, common exception type, per-tag breakdown
- Rich environment — Python, Behave, platform, OS, hostname, CI provider, cwd, command, user, CPU count, memory, git branch/commit/remote
- Arbitrary metadata — inject domain-specific context via
[behave.userdata]withmjr.*keys - Cucumber JSON format —
CucumberJSONFormatteroutputs de facto Cucumber JSON for compatibility with cucumber-reporting, ReportPortal, Jenkins plugins, and more - Zero Behave dependency in the serializer — the JSON model is portable
- JSON Schema validation with helpful error messages
- Configurable — pretty/compact, embed/exclude attachments, exclude passed scenarios
- Production-ready — 123 tests, lint, type-check, CI
Installation
pip install behave-modern-json-report[behave]
For validation support:
pip install behave-modern-json-report[validate]
For enhanced environment detection (memory info):
pip install behave-modern-json-report[env]
For development:
pip install behave-modern-json-report[dev]
Quick Start
As a Behave formatter (modern JSON)
behave --format behave_modern_json_report:ModernJSONFormatter --outfile report.json
As a Behave formatter (Cucumber JSON)
behave --format behave_modern_json_report:CucumberJSONFormatter --outfile cucumber.json
The Cucumber JSON format is compatible with tools that consume Cucumber JSON reports:
- cucumber-reporting (Jenkins plugin)
- multiple-cucumber-html-reporter
- ReportPortal, Allure, and other CI/CD integrations
With metadata via behave.ini
[behave]
format = behave_modern_json_report:ModernJSONFormatter
outfile = report.json
[behave.userdata]
mjr.project_name = My Project
mjr.branch = dev
mjr.team = qa
mjr.environment = staging
mjr.build_id = 42
All keys prefixed with mjr. are automatically injected into the report's metadata block. mjr.project_name is used as the project name. The prefix is stripped in the output:
{
"execution": { "projectName": "My Project" },
"metadata": { "data": { "branch": "dev", "team": "qa", "environment": "staging", "build_id": "42" } }
}
You can also pass metadata via CLI:
behave --userdata "mjr.branch=hotfix,mjr.build_id=99" --format behave_modern_json_report:ModernJSONFormatter --outfile report.json
Programmatically
from behave_modern_json_report import serialize, SerializerOptions
from behave_modern_json_report.collector import Collector
collector = Collector(project_name="my-app", metadata={"branch": "main"})
# Feed Behave events to the collector...
# collector.start_feature(feature)
# collector.start_scenario(scenario)
# collector.start_step(step)
# collector.end_step(step)
# collector.end_scenario(scenario)
# collector.end_feature(feature)
report = collector.finalize()
json_str = serialize(report, options=SerializerOptions(pretty=True))
Validation
from behave_modern_json_report import validate_json
result = validate_json(open("report.json").read())
if not result:
for error in result.errors:
print(f"{error.path}: {error.message}")
JSON Structure
{
"schemaVersion": "1.0.0",
"execution": {
"executionId": "exec-...",
"projectName": "my-app",
"startTime": "2026-06-30T14:20:00.000Z",
"endTime": "2026-06-30T14:20:01.500Z",
"duration": 1.5,
"status": "passed",
"command": "behave ...",
"workingDirectory": "/home/user/project"
},
"statistics": {
"features": 1,
"scenarios": 3,
"steps": 12,
"passed": 12,
"failed": 0,
"skipped": 0,
"undefined": 0,
"pending": 0,
"passRate": 1.0,
"duration": 1.5,
"errorCount": 0,
"totalAttachments": 0,
"totalLogs": 0,
"slowestStepDuration": 0.2,
"avgScenarioDuration": 0.5
},
"environment": {
"pythonVersion": "3.12.3",
"behaveVersion": "1.2.6",
"platform": "linux",
"os": "Linux",
"osVersion": "6.5.0",
"hostname": "build-agent-01",
"ciProvider": "github-actions",
"cwd": "/home/user/project",
"command": "behave --format json-modern",
"user": "tester",
"cpuCount": 8,
"memoryMb": 16384,
"gitBranch": "main",
"gitCommit": "abc1234",
"gitRemote": "origin"
},
"features": [
{
"id": "feature-...",
"name": "Calculator",
"tags": ["smoke"],
"status": "passed",
"duration": 1.5,
"scenarios": [
{
"id": "scenario-...",
"name": "Add two numbers",
"featureId": "feature-...",
"status": "passed",
"duration": 0.5,
"steps": [
{
"id": "step-...",
"keyword": "Given",
"text": "I have entered 5 into the calculator",
"status": "passed",
"duration": 0.1
}
]
}
]
}
],
"metadata": {
"data": {
"browser": "Chrome",
"environment": "QA",
"branch": "main"
}
}
}
See examples/golden-report.json for a complete example.
Configuration
SerializerOptions controls the output:
from behave_modern_json_report import SerializerOptions
opts = SerializerOptions(
pretty=True, # Indented JSON
include_environment=True, # Include environment block
include_attachments=True, # Include attachment metadata
embed_attachments=True, # Embed attachment content inline
exclude_passed_scenarios=False, # Drop passed scenarios (failure-only)
indent=2, # Indentation level
sort_keys=False, # Sort keys lexicographically
ensure_ascii=False, # Escape non-ASCII characters
)
Architecture
Behave Events → Collector → Execution Model → Serializer → JSON
Only collector.py and formatter.py depend on Behave. The model, serializer, validator and statistics modules are pure Python.
See docs/architecture.md for details.
Documentation
Project Structure
behave-modern-json-report/
├── behave_modern_json_report/
│ ├── __init__.py
│ ├── formatter.py # Modern JSON Formatter API entrypoint
│ ├── cucumber_formatter.py # Cucumber JSON Formatter API entrypoint
│ ├── cucumber_serializer.py # Model → Cucumber JSON (no Behave dep)
│ ├── collector.py # Behave events → model (only Behave dep)
│ ├── serializer.py # Model → JSON (no Behave dep)
│ ├── schema.py # Schema version constants
│ ├── validator.py # JSON Schema + runtime validation
│ ├── models.py # Execution model dataclasses
│ ├── statistics.py # Statistics aggregator
│ ├── environment.py # Runtime environment detection
│ ├── attach.py # High-level attachment helpers for hooks
│ ├── utils.py # IDs, timing, status, MIME helpers
│ └── schemas/
│ └── execution.schema.json
├── examples/
│ ├── behave_project/ # Real behave project example
│ │ ├── behave.ini
│ │ ├── run.py
│ │ └── features/
│ ├── calculator.feature
│ └── golden-report.json
├── docs/
├── tests/
├── .github/
│ └── workflows/
│ ├── ci.yml
│ └── release.yml
├── pyproject.toml
├── Makefile
├── README.md
├── LICENSE
└── CHANGELOG.md
Testing
python -m pytest tests/ -v
Test suites:
- Unit tests — utils, statistics, environment, attachments
- Schema validation tests — golden report, invalid reports
- Serialization tests — all model fields, options, backgrounds, rules
- Cucumber serializer tests — status mapping, embeddings, output, backgrounds, outlines
- Regression tests — collector lifecycle, formatter output
- Golden JSON tests — structural stability
License
MIT — see LICENSE.
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 behave_modern_json_report-1.1.0.tar.gz.
File metadata
- Download URL: behave_modern_json_report-1.1.0.tar.gz
- Upload date:
- Size: 43.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d426a2b5dff2d9a36825b9c5de491f23c8317856652c7216bd91891576ebf255
|
|
| MD5 |
1ba1bec43cec35ba6ab5dba9981358e6
|
|
| BLAKE2b-256 |
e6fdc2c84f49b01848c8f09609d298e29fd24b7be2a7537eb5518b76cae7d261
|
Provenance
The following attestation bundles were made for behave_modern_json_report-1.1.0.tar.gz:
Publisher:
release.yml on MathiasPaulenko/behave-modern-json-report
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
behave_modern_json_report-1.1.0.tar.gz -
Subject digest:
d426a2b5dff2d9a36825b9c5de491f23c8317856652c7216bd91891576ebf255 - Sigstore transparency entry: 2024282769
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/behave-modern-json-report@e7e4e8d6de623b7490ac6cbb52956537fd6b6ec4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e7e4e8d6de623b7490ac6cbb52956537fd6b6ec4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file behave_modern_json_report-1.1.0-py3-none-any.whl.
File metadata
- Download URL: behave_modern_json_report-1.1.0-py3-none-any.whl
- Upload date:
- Size: 36.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5be7e9cb44f53041390e995c62026bbee5c50d2bb787515f6600a1d6e0ea3fd5
|
|
| MD5 |
0e0f05288a96ab3a45d3e8dce682ce3d
|
|
| BLAKE2b-256 |
491d6ddfbc61adc47c7c3c63631a8f59d91027554ca7c690392a9ce8d7bbe63a
|
Provenance
The following attestation bundles were made for behave_modern_json_report-1.1.0-py3-none-any.whl:
Publisher:
release.yml on MathiasPaulenko/behave-modern-json-report
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
behave_modern_json_report-1.1.0-py3-none-any.whl -
Subject digest:
5be7e9cb44f53041390e995c62026bbee5c50d2bb787515f6600a1d6e0ea3fd5 - Sigstore transparency entry: 2024282889
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/behave-modern-json-report@e7e4e8d6de623b7490ac6cbb52956537fd6b6ec4 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e7e4e8d6de623b7490ac6cbb52956537fd6b6ec4 -
Trigger Event:
push
-
Statement type: