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 50 built-in rules across 9 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 |
| Hardcoded passwords leak into version control | BSEC001 flags hardcoded secrets |
| Ableist language goes unnoticed in tests | BACC001 suggests inclusive alternatives |
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
- 50 built-in rules across 9 categories: correctness, step definitions, consistency, complexity, style, pedantic, security, i18n, and accessibility.
- 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 | 10 | Error |
| Step Definitions | BD | 5 | Warning |
| Consistency | BK | 5 | Warning / Info |
| Complexity | BX | 6 | Warning |
| Style | BS | 8 | Warning |
| Pedantic | BP | 7 | Info |
| Security | BSEC | 3 | Error |
| I18N | BI18N | 3 | Warning |
| Accessibility | BACC | 3 | Warning |
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
Full documentation is hosted at mathiaspaulenko.github.io/behave-lint.
User guide
Rules
- Rules Overview
- Correctness (BC)
- Step Definitions (BD)
- Consistency (BK)
- Complexity (BX)
- Style (BS)
- Pedantic (BP)
- Security (BSEC)
- I18N (BI18N)
- Accessibility (BACC)
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
Release files for behave-lint 2.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| behave_lint-2.4.1.tar.gz | 184.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| behave_lint-2.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 313.6 kB
Release files / behave_lint-2.4.1.tar.gz
| Download URL | behave_lint-2.4.1.tar.gz |
|---|---|
| Size | 184.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
633823edc7cfbaef1ac0b97446e0ba2d6b3aa3639d6b55461695ca6571cc6808
|
|
BLAKE2b-256 checksum How to use checksums |
85251c2e8cbf20c9e86fdb5071738abacc8c136c013ada527a965ea8347bd7cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 29, 2026.
Transparency logRelease files / behave_lint-2.4.1-py3-none-any.whl
| Download URL | behave_lint-2.4.1-py3-none-any.whl |
|---|---|
| Size | 129.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4d21f466cf27b34de524e96355b3947a99aa682f242d342885a0d3046b3cc519
|
|
BLAKE2b-256 checksum How to use checksums |
202b39b0ea4094a2780ec153e53db53a4ca9dc4369da6cee274159d4cd571de0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 29, 2026.
Transparency log