Skip to main content

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.

CI Python 3.11+ License: MIT Schema Version


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 helpersattach_file, attach_text, attach_json, attach_screenshot, log for environment.py hooks
  • 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 outlinesisOutline and outlineName fields
  • Expanded statusespassed, 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] with mjr.* keys
  • 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 — 101 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

behave --format behave_modern_json_report:ModernJSONFormatter --outfile report.json

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        # Behave Formatter API entrypoint
│   ├── 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
  • Regression tests — collector lifecycle, formatter output
  • Golden JSON tests — structural stability

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

behave_modern_json_report-1.0.0.tar.gz (37.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

behave_modern_json_report-1.0.0-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file behave_modern_json_report-1.0.0.tar.gz.

File metadata

File hashes

Hashes for behave_modern_json_report-1.0.0.tar.gz
Algorithm Hash digest
SHA256 9b423fc09dd73ac885fa71c9d483f986387e5eeef0b6fd924d10c53a4275fd6b
MD5 676d439afc89d99874998c9794d78fdc
BLAKE2b-256 89c4fa3b5d35f54e20891a9e47afc4aa634ced629cacd8b118bfb20384b51510

See more details on using hashes here.

Provenance

The following attestation bundles were made for behave_modern_json_report-1.0.0.tar.gz:

Publisher: release.yml on MathiasPaulenko/behave-modern-json-report

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file behave_modern_json_report-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for behave_modern_json_report-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 91c0063e67d1d7171cf13e44404184328a12ddfaa6a1725e10fd55eb0af13055
MD5 5c5b20ddc54a4eac0e7855093e8f6738
BLAKE2b-256 1e9e1a5e190781afa543cf945b9c53531de328e29d3dca30a090f28c423635a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for behave_modern_json_report-1.0.0-py3-none-any.whl:

Publisher: release.yml on MathiasPaulenko/behave-modern-json-report

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page