A fast, opinionated, extensible linter for Gherkin .feature files and Behave test suites.
Project description
behave-lint
A fast, opinionated, extensible linter for Gherkin
.featurefiles and Behave test suites.
behave-lint statically analyzes your Gherkin feature files for correctness, consistency, complexity, and style — without executing a single test. It ships with 41 built-in rules across 6 categories, supports auto-fix for 14 rules, and outputs in 5 formats including SARIF for GitHub Code Scanning. Includes watch mode for real-time feedback during development.
Why behave-lint?
| Without behave-lint | With behave-lint |
|---|---|
| Duplicate step definitions cause silent match failures | BD001 detects duplicates at lint time |
| Inconsistent tag casing breaks CI filters | BS001 auto-fixes to snake_case |
| Trailing punctuation in steps clutters reports | BD005 strips it automatically |
| No Given-When-Then ordering enforcement | BC001 catches structural violations |
| Feature files grow unchecked in complexity | BX001-BX005 enforce limits |
Installation
pip install behave-lint
Or with uv:
uv add behave-lint
For watch mode, install the optional dependency:
pip install behave-lint[watch]
For LSP support (VS Code, Neovim, Emacs):
pip install behave-lint[lsp]
Quick start
# Lint all feature files
behave-lint features/
# Apply safe auto-fixes
behave-lint features/ --fix
# Watch for changes and re-lint automatically
behave-lint features/ --watch
# JSON output for CI integration
behave-lint features/ --output json --output-file report.json
# SARIF for GitHub Code Scanning
behave-lint features/ --output sarif --output-file results.sarif
# List all available rules
behave-lint --list-rules
# Explain a specific rule
behave-lint --explain BC001
Features
- 41 built-in rules across 6 categories: correctness, step definitions, consistency, complexity, style, and pedantic.
- Auto-fix — 14 rules with safe and unsafe fixes (
--fix,--unsafe-fixes). - Watch mode — re-lint on file changes with
--watch(requirespip install behave-lint[watch]). - LSP server — real-time diagnostics in VS Code, Neovim, Emacs
(requires
pip install behave-lint[lsp]). - 5 output formats — console (colored), JSON, SARIF, Markdown, and GitHub Actions inline annotations.
- Zero-config — sensible defaults work out of the box. Override
anything via
[tool.behave-lint]inpyproject.toml. - Plugin system — write custom rules and reporters as Python packages. Register via entry points.
- CI/CD ready — deterministic output, clear exit codes, SARIF integration with GitHub Code Scanning.
- Fast — sub-second on typical projects through caching and parallel execution.
Rules
| Category | Prefix | Rules | Default Severity |
|---|---|---|---|
| Correctness | BC | 6 | Error |
| Step Definitions | BD | 5 | Warning |
| Consistency | BK | 5 | Warning / Info |
| Complexity | BX | 5 | Warning |
| Style | BS | 5 | Warning |
| Pedantic | BP | 5 | Info |
Auto-fixable rules
| Rule | Fix | Safety |
|---|---|---|
| BC004 | Replace invalid tag characters with _ |
Safe |
| BD004 | Convert {param} → <param> |
Safe |
| BD005 | Remove trailing punctuation from steps | Safe |
| BS001 | Convert tags to snake_case |
Safe |
| BS005 | Insert missing Feature description template | Unsafe |
| BP001 | Insert @smoke tag on untagged scenarios |
Unsafe |
| BP005 | Append Valid values to unnamed Examples |
Unsafe |
| BP006 | Insert As a / I want / So that description | Unsafe |
See the Auto-Fix guide for the full list.
Configuration
Configure behave-lint in your pyproject.toml:
[tool.behave-lint]
select = ["BC001", "BC002", "BS001"]
ignore = ["BP001", "BP002"]
fail-on = "warning"
exclude = ["features/wip/"]
[tool.behave-lint.severity]
BK001 = "info"
[tool.behave-lint.rules]
BX001 = { max-steps = 8 }
BP003 = { min-length = 5 }
Precedence (lowest → highest):
- Built-in defaults
pyproject.toml[tool.behave-lint]- Environment variables (
BEHAVE_LINT_*) - CLI flags
See the Configuration guide for all options.
CI/CD integration
GitHub Actions with SARIF
- run: pip install behave-lint
- run: behave-lint features/ --sarif --output-file behave-lint.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: behave-lint.sarif
Inline annotations
- run: behave-lint features/ --output github
See the CI/CD guide for full workflows.
Output formats
| Format | Flag | Use case |
|---|---|---|
| Console | --output console |
Local development (default) |
| JSON | --json |
CI pipelines, custom tooling |
| SARIF | --sarif |
GitHub Code Scanning |
| Markdown | --output markdown |
PR comments, reports |
| GitHub | --output github |
Inline PR annotations |
See the Output Formats reference for schema details.
Examples
Runnable example projects in the examples/ directory:
| Example | Description |
|---|---|
| basic-usage | Minimal project with configuration |
| auto-fix | Before/after demo of --fix |
| ci-cd | GitHub Actions with SARIF upload |
| custom-rules | Custom rule plugin with entry points |
Documentation
User guide
Rules
- Rules Overview
- Correctness (BC)
- Step Definitions (BD)
- Consistency (BK)
- Complexity (BX)
- Style (BS)
- Pedantic (BP)
Guides
Design documents
- Vision — project vision and mission
- Specification — full feature specification
- Architecture — internal architecture
- API — public API specification
- Rule Engine Design — rule lifecycle and execution
- Rule Taxonomy — rule categories and metadata
- Configuration System — configuration schema
- Implementation Roadmap — milestone plan
Development
git clone https://github.com/MathiasPaulenko/behave-lint.git
cd behave-lint
uv sync
uv run pre-commit install
# Run tests
uv run pytest
# Lint
uv run ruff check behave_lint/ tests/
# Type check
uv run mypy behave_lint/
# Build docs
uv run mkdocs build --strict
See CONTRIBUTING.md for detailed contribution guidelines, coding standards, and PR workflow.
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_lint-2.3.0.tar.gz.
File metadata
- Download URL: behave_lint-2.3.0.tar.gz
- Upload date:
- Size: 172.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a0c4c4320f2fc1c3cf5be18755c7c599619069546db91d0a8f657e7ee2726cf
|
|
| MD5 |
cc5afc3ed0c3d27734c360df6dfbba1d
|
|
| BLAKE2b-256 |
e49641111c6e85ca786f23b0a42a882e0fb211e17733dab8278f7ee98227d7dd
|
Provenance
The following attestation bundles were made for behave_lint-2.3.0.tar.gz:
Publisher:
release.yml on MathiasPaulenko/behave-lint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
behave_lint-2.3.0.tar.gz -
Subject digest:
4a0c4c4320f2fc1c3cf5be18755c7c599619069546db91d0a8f657e7ee2726cf - Sigstore transparency entry: 2062275948
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/behave-lint@39b984e786f9d3e993f99316d41a7ae5d16b1dd1 -
Branch / Tag:
refs/tags/v2.3.0 - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@39b984e786f9d3e993f99316d41a7ae5d16b1dd1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file behave_lint-2.3.0-py3-none-any.whl.
File metadata
- Download URL: behave_lint-2.3.0-py3-none-any.whl
- Upload date:
- Size: 120.5 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 |
518d28d8c3b2d3249f164d385bbb746b41987e69ad5c6840ec99d09a73abc684
|
|
| MD5 |
a0d25af9fbad605ab1925f412ee4f62e
|
|
| BLAKE2b-256 |
80ebda9d6d1d6a5e2de723e22b7e337672c40ef6c225e1b3b0ea428abde582cc
|
Provenance
The following attestation bundles were made for behave_lint-2.3.0-py3-none-any.whl:
Publisher:
release.yml on MathiasPaulenko/behave-lint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
behave_lint-2.3.0-py3-none-any.whl -
Subject digest:
518d28d8c3b2d3249f164d385bbb746b41987e69ad5c6840ec99d09a73abc684 - Sigstore transparency entry: 2062276048
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/behave-lint@39b984e786f9d3e993f99316d41a7ae5d16b1dd1 -
Branch / Tag:
refs/tags/v2.3.0 - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@39b984e786f9d3e993f99316d41a7ae5d16b1dd1 -
Trigger Event:
push
-
Statement type: