Skip to main content

behave-modern-sheets-report

CI Release PyPI version Python versions License: MIT Coverage Code style: ruff Type checker: mypy Stable SemVer

Modern spreadsheet report formatters for Behave BDD — generate CSV, XLSX, and ODS execution reports with multi-sheet layouts, conditional formatting, and automatic trend history.


Table of Contents

Features

Feature Description
📊 Three output formats CSV (stdlib, zero dependencies), XLSX (via openpyxl), and ODS (via odfpy)
📑 Multi-sheet workbooks Summary, Details, Failures, and Trends sheets in XLSX and ODS
🎨 Conditional formatting Color-coded pass/fail cells for at-a-glance status reading
📈 Automatic trend history XLSX and ODS runs are persisted to a JSON file and visualized in a Trends sheet
⚙️ Configurable columns Choose which columns appear in the Details sheet via userdata
🔒 Atomic history writes Corruption-proof file I/O using temp file + os.replace
✅ 100% test coverage Fully tested across Python 3.11, 3.12, 3.13, and 3.14 on Linux, Windows, and macOS
🪶 Zero required dependencies CSV works with Python stdlib alone; XLSX and ODS are opt-in extras

Requirements

  • Python 3.11 or higher
  • Behave >= 1.2.6 (for running BDD tests)
  • openpyxl >= 3.1 (optional, for XLSX output)
  • odfpy >= 1.4 (optional, for ODS output)

Installation

pip install behave-modern-sheets-report

Extras

Extra Packages When to use
[behave] behave>=1.2.6 You need Behave installed alongside the formatter
[xlsx] openpyxl>=3.1 You want XLSX output
[ods] odfpy>=1.4 You want ODS output
[dev] pytest, ruff, mypy, build, twine Local development

Install with multiple extras:

pip install "behave-modern-sheets-report[xlsx,ods]"

For full development setup:

git clone https://github.com/MathiasPaulenko/behave-modern-sheets-report.git
cd behave-modern-sheets-report
pip install -e ".[dev,xlsx,ods]"
pre-commit install

Quick Start

  1. Register the formatters in your behave.ini (or the [behave.formatters] section of setup.cfg/tox.ini):

    [behave.formatters]
    csv-modern = behave_modern_sheets_report.csv_formatter:CSVFormatter
    xlsx-modern = behave_modern_sheets_report.xlsx_formatter:XLSXFormatter
    ods-modern = behave_modern_sheets_report.ods_formatter:ODSFormatter
    
  2. Run Behave with any (or all) of the formatters:

    behave -f xlsx-modern -o report.xlsx
    
  3. Open report.xlsx in Excel, LibreOffice, or Google Sheets.

A ready-to-run demo lives in examples/behave_project — it includes a behave.ini with the formatters already registered and features covering backgrounds, scenario outlines, and a failing step.

Format Comparison

Feature CSV XLSX ODS
Dependency stdlib openpyxl odfpy
Multi-sheet Single file Yes Yes
Conditional formatting — Cell fills Cell styles
Auto-filters — Yes —
Freeze panes — Yes —
Bold headers — Yes Yes
Trends sheet — Yes Yes
Install extra — [xlsx] [ods]

Report Structure

XLSX and ODS reports contain up to four sheets:

Sheet Content When present
Summary One row per feature: name, tags, scenario totals, pass rate, duration Always
Details One row per scenario with configurable columns Always
Failures Failed scenarios only — error message, type, traceback, file, line Always (empty if no failures)
Trends One row per recorded run: timestamp, pass rate, totals, duration Always (one entry per run)

CSV reports produce a single flat file with one row per scenario (equivalent to the Details sheet).

Conditional formatting colors

Status Cell fill
Passed Green (#C6EFCE)
Failed Red (#FFC7CE)
Skipped Yellow (#FFEB9C)

Status mapping

Behave statuses are normalized into canonical values:

Behave status Reported as
passed, xfailed, xpassed passed
failed, error, hook_error, cleanup_error failed
skipped skipped
undefined, pending undefined
Anything else untested

CLI Usage

Register the formatters in behave.ini (Behave does not discover entry points automatically):

[behave.formatters]
csv-modern = behave_modern_sheets_report.csv_formatter:CSVFormatter
xlsx-modern = behave_modern_sheets_report.xlsx_formatter:XLSXFormatter
ods-modern = behave_modern_sheets_report.ods_formatter:ODSFormatter

Generate reports:

behave -f csv-modern -o report.csv
behave -f xlsx-modern -o report.xlsx
behave -f ods-modern -o report.ods

Multiple formatters can be used simultaneously to produce all formats in a single run:

behave -f csv-modern -o report.csv -f xlsx-modern -o report.xlsx -f ods-modern -o report.ods

If -o is omitted, CSV output goes to stdout and XLSX/ODS reports are written to report.xlsx/report.ods in the current directory.

You can also set userdata options directly in behave.ini:

[behave.userdata]
report_columns = feature,scenario,status,duration,error
report_only_failed = false
report_delimiter = comma
report_clear_history = false
report_history_path = .behave-sheets-history.json
report_max_history = 100

Configuration Options

All options are passed via Behave's userdata (command-line -D or behave.ini):

Option Type Default Description
report_columns CSV string feature,scenario,status,duration,tags,error Columns shown in Details sheet / CSV rows
report_only_failed bool false Show only failed scenarios in Details / CSV
report_delimiter string comma CSV delimiter (comma, semicolon, tab)
report_clear_history bool false Clear history before appending current run
report_history_path string .behave-sheets-history.json Path to history JSON file
report_max_history int 100 Maximum history entries to retain

Examples

Generate an XLSX report with only failed scenarios and a custom column set:

behave -f xlsx-modern -o report.xlsx \
  -D report_only_failed=true \
  -D report_columns=feature,scenario,status,error \
  -D report_max_history=50

Use a semicolon delimiter for CSV (useful in European locales):

behave -f csv-modern -o report.csv -D report_delimiter=semicolon

Clear history before a fresh run (e.g. after changing the test suite):

behave -f xlsx-modern -o report.xlsx -D report_clear_history=true

Store history in a custom location (e.g. outside the working directory):

behave -f xlsx-modern -o report.xlsx -D report_history_path=/tmp/behave-history.json

Available Columns

The report_columns option accepts any combination of the following column names (comma-separated):

Column Description
feature Feature name
scenario Scenario name
status Scenario status (passed, failed, skipped, undefined; untested in dry runs)
duration Execution time (human-readable, e.g. 1.234s, 12ms)
tags Scenario tags (semicolon-separated)
error Error message with type appended if available (e.g. Something went wrong [AssertionError])
error_type Exception type name
traceback Full traceback string
steps Total step count (including background steps)
passed_steps Number of passed steps
failed_steps Number of failed steps
skipped_steps Number of skipped steps
file Feature file path
line Line number in the feature file
rule Gherkin rule name (empty if none)
is_outline true if scenario outline example row, false otherwise
feature_tags Feature-level tags (semicolon-separated)
background_steps Number of background steps executed before the scenario
has_data_table true if any step includes a Gherkin data table
has_docstring true if any step includes a Gherkin docstring

Default columns: feature,scenario,status,duration,tags,error. Unknown column names are ignored; if none of the given names is valid, the defaults are used.

Every XLSX and ODS run is automatically appended to a JSON history file (.behave-sheets-history.json in the working directory by default); CSV output does not record history. The history feeds the Trends sheet, showing pass rate evolution across runs.

  • report_history_path — custom location for the history file.
  • report_clear_history — clears all previous entries before appending the current run (useful for fresh starts).
  • report_max_history — limits the number of retained entries (oldest are dropped).

History is managed atomically (write to .tmp, then os.replace) to prevent corruption.

History file format

The history file is a JSON array of entry objects:

[
  {
    "run_id": "run_a1b2c3d4e5f6",
    "timestamp": "2025-01-15T10:30:00.123456+00:00",
    "total_features": 3,
    "total_scenarios": 15,
    "passed": 14,
    "failed": 1,
    "skipped": 0,
    "undefined": 0,
    "pass_rate": 93.3,
    "duration": 2.45
  }
]

Programmatic Usage

You can use the collector, writers, and history directly without Behave:

from behave_modern_sheets_report import Collector, CSVWriter, XLSXWriter, History
from pathlib import Path

# Collect results from Behave events
collector = Collector()
collector.start_feature(feature_obj)
collector.start_scenario(scenario_obj)
# Behave announces every step upfront, then reports one result per executed step
for step in scenario_steps:
    collector.start_step(step)
for step in executed_steps:
    collector.end_step(step)
collector.end_scenario()
collector.end_feature()
run_summary = collector.finalize()

# Write CSV (no extra dependencies needed)
with open("report.csv", "w", newline="") as f:
    CSVWriter.write(run_summary, f)

# Write XLSX (requires openpyxl)
history = History(max_entries=50)
trends = history.append(run_summary)
XLSXWriter.write(run_summary, Path("report.xlsx"), trends=trends)

This is useful for integrating the report generation into custom test runners or CI pipelines.

Architecture

Behave Runner
    │
    ├── CSVFormatter ──► Collector ──► RunSummary ──► CSVWriter ──► report.csv
    ├── XLSXFormatter ──► Collector ──► RunSummary ──► XLSXWriter ──► report.xlsx
    └── ODSFormatter ───► Collector ──► RunSummary ──► ODSWriter ───► report.ods
                                        │
                                        └──► History ──► .behave-sheets-history.json
                                                │
                                                └──► Trends sheet

Collector processes Behave events (feature, scenario, step, result) and builds a RunSummary. Writers serialize the summary into the target format. History persists run metrics between executions for trend analysis.

Key design decisions

  • Pure data models — models.py has zero external dependencies. Dataclasses can be serialized to any format without importing Behave, openpyxl, or odfpy.
  • Single Behave integration point — Collector is the only module that touches Behave objects. Everything else operates on pure dataclasses, making the writers and history fully testable without Behave.
  • Opt-in dependencies — CSV works with stdlib alone. openpyxl and odfpy are only imported when their respective writer is called.
  • Atomic file I/O — History writes to a .tmp file first, then uses os.replace for an atomic swap. This prevents corruption if the process is killed mid-write.

Ecosystem

Part of the behave-modern-* formatter family:

Package Formats Status
behave-modern-json-report JSON ✅
behave-modern-html-report HTML ✅
behave-modern-md-report Markdown ✅
behave-modern-console-report Console (rich terminal) ✅
behave-modern-sheets-report CSV, XLSX, ODS this package

Contributing

Contributions are welcome! Please read the Contributing Guide and our Code of Conduct before submitting pull requests.

Development commands

make lint        # ruff check + format check
make typecheck   # mypy --strict
make test        # pytest with verbose output
make format      # ruff auto-fix + format
make build       # build sdist + wheel

Security

If you discover a security vulnerability, please refer to our Security Policy for responsible disclosure instructions.

Changelog

See CHANGELOG.md for release history and notable changes.

License

MIT — see LICENSE for full text.


Made with care by Mathias Paulenko

Metadata

Release files for behave-modern-sheets-report 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for behave-modern-sheets-report 1.2.0
File Size Uploaded
behave_modern_sheets_report-1.2.0.tar.gz 60.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for behave-modern-sheets-report 1.2.0
File Interpreter ABI Platform
behave_modern_sheets_report-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 92.8 kB

Release files / behave_modern_sheets_report-1.2.0.tar.gz

Download URL behave_modern_sheets_report-1.2.0.tar.gz
Size 60.6 kB
Tags Source
SHA-256 checksum
How to use checksums
970c6c547137dd2dd17a6cd11312cfd04bb8d3606538dc577323eaa836d1f737
BLAKE2b-256 checksum
How to use checksums
076b6704eda42c20c80223fd03f49aad6567b925b66ddbe94bb14d0fd74ad81d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / behave_modern_sheets_report-1.2.0-py3-none-any.whl

Download URL behave_modern_sheets_report-1.2.0-py3-none-any.whl
Size 32.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9ee13d55232c3b36554dddd0bd6b487e1ab5e52a528dfea251a704e7139788e6
BLAKE2b-256 checksum
How to use checksums
83764913cda77c17c679d2bf26c312ae11559fefc65c43aa3a6e008c7d70ab39
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page