Skip to main content

The opinionated formatter for Behave .feature files

Project description

behave-format

The opinionated formatter for Behave .feature files.

Black is for Python. gofmt is for Go. behave-format is for Gherkin.


Overview

behave-format is a deterministic, opinionated formatter for Behave .feature files. It consumes the canonical domain model from behave-model and produces clean, consistent, beautifully formatted output.

Key principle: behave-format does NOT parse Gherkin. It does NOT lint. It does NOT validate. It ONLY transforms a behave-model.Project into formatted .feature files.

.feature files → behave-model (domain model) → behave-format → formatted .feature files

Features

  • Opinionated — minimal configuration, sensible defaults
  • Deterministic — same input always produces same output
  • Idempotentformat(format(x)) == format(x)
  • Fast — handles thousands of feature files efficiently
  • CI-friendly--check mode with exit code 1 when formatting is needed
  • Safe — never changes semantics (names, step text, table values, docstrings)

Installation

pip install behave-format

Quick Start

CLI

# Format files in place (default)
behave-format features/

# Check mode (CI) — exit 1 if formatting is needed
behave-format --check features/

# Diff mode — show differences without writing
behave-format --diff features/

Python API

from behave_model import load_project
from behave_format import format_project, render_project, Settings

project = load_project("features/")

# Format the project model in place
format_project(project)

# Or render to text
text = render_project(project, Settings())

Formatting Rules

Tags

Tags are sorted alphabetically by default:

@api @smoke

Features

  • One blank line before each Feature
  • Clean title formatting

Scenarios

  • One blank line before each Scenario
  • Two-space indentation for steps
  Given user exists
  When user logs in
  Then dashboard is shown

Tables

Tables are always aligned:

Before:

|user|password|
|john|123|

After:

| user | password |
| john | 123      |

Blank Lines

  • No trailing blank lines
  • No multiple consecutive empty lines
  • Consistent spacing between blocks

Indentation

  • Spaces only (no tabs)
  • Default: 2 spaces

Configuration

Minimal configuration via pyproject.toml:

[tool.behave-format]
indent = 2
sort_tags = true
sort_features = false
sort_scenarios = false
line_length = 120
Option Default Description
indent 2 Number of spaces for indentation
sort_tags true Sort tags alphabetically
sort_features false Sort features by name
sort_scenarios false Sort scenarios by name
line_length 120 Maximum line length (reference)

Before / After

Before

@smoke @auth
Feature: Login
  As a user
  I want to log in

  Background:
    Given a database connection

  @happy
  Scenario: Successful login
    Given the user is on the login page
    When the user enters "admin" and "password"
    Then the user should be logged in

After

@auth @smoke
Feature: Login
  As a user
  I want to log in

  Background:
    Given a database connection

  @happy
  Scenario: Successful login
    Given the user is on the login page
    When the user enters "admin" and "password"
    Then the user should be logged in

Architecture

behave_format/
├── config/
│   └── settings.py        # Settings dataclass + pyproject.toml loader
├── pipeline/
│   ├── normalize.py       # Whitespace, indentation, tag normalization
│   ├── sort.py            # Sort tags, features, scenarios
│   ├── align.py           # Table alignment, trailing whitespace
│   ├── rules.py           # Formatting rules registry
│   └── formatter.py       # Main orchestrator (format_project)
├── printer/
│   ├── feature_printer.py
│   ├── scenario_printer.py
│   ├── step_printer.py
│   ├── table_printer.py
│   └── tag_printer.py
└── cli/
    └── main.py            # CLI entry point

Pipeline

  1. Normalize — clean whitespace, standardize indentation, normalize tags
  2. Sort — order tags (alphabetically by default), optionally features and scenarios
  3. Align — align table columns, remove trailing spaces
  4. Print — convert behave-model.feature text (deterministic)

Safety

The formatter NEVER changes semantics:

  • Feature names: preserved
  • Scenario names: preserved
  • Step text: preserved (only whitespace normalized)
  • DocString content: preserved
  • Table values: preserved (only alignment changes)
  • Comments content: preserved

Integration

behave-format integrates naturally with the Behave ecosystem:

Development

pip install -e ".[dev]"
pytest tests/ -v
ruff check .
ruff format --check .

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Run ruff check . and pytest tests/ before submitting
  4. Open a Pull Request

License

MIT

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_format-1.0.0.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

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

behave_format-1.0.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: behave_format-1.0.0.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for behave_format-1.0.0.tar.gz
Algorithm Hash digest
SHA256 139b5c6320a42cf1e6030f01b24c405ae8d679707695c191f6892b20b1145b93
MD5 df45dc93ac99a95b5cf1f27cfb1eba03
BLAKE2b-256 d7181c928a243131a2c4f6e73974576f880afca7b90045057ef86f8abf668333

See more details on using hashes here.

Provenance

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

Publisher: release.yml on MathiasPaulenko/behave-format

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_format-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: behave_format-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for behave_format-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7b0f10b3e46a8d7de8d8fc3587464ab8ae255eda758c1bfd4da0ff222a860c95
MD5 b436935cc3723794b4d51313898c2bb2
BLAKE2b-256 a482bacc8baee950cc0f306dfe3bdaebee4fc19fcbed736781cec65aea44c167

See more details on using hashes here.

Provenance

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

Publisher: release.yml on MathiasPaulenko/behave-format

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