behave

A Python behavior-driven development framework that runs Gherkin feature files against step definitions written in plain Python.

Framework
PyPI
v1.3.3
3,524stars
BSD-2-Clause

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
77/100Good
Development Activity72
Maintenance48
Community88
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture85
Code Quality80
Innovation65
Learning Curve85

Behave brings behavior-driven development (BDD) to Python. Teams write executable specifications as .feature files in Gherkin — the same natural-language Given/When/Then syntax used by Cucumber — and back each step with a Python function decorated with @given, @when, or @then. Running the behave CLI discovers features/ directories, parses the Gherkin, matches each step against the registered step implementations, and reports pass/fail results with pluggable formatters (plain text, JSON, pretty, progress, JUnit-style rerun files).

The project has been maintained since 2011 and is the de facto standard BDD tool in the Python ecosystem, used to bridge collaboration between developers, QA, and non-technical stakeholders who can read and review feature files without touching code. It layers in tag expressions for selective test runs, fixtures and hooks for setup/teardown, async step support for asyncio-based codebases, and integrates with parse/parse-type and Cucumber Expressions for flexible step-text matching.

What You Get

  • A behave CLI that discovers features/ and features/steps/ directories and runs Gherkin scenarios end to end
  • @given/@when/@then/@step decorators for wiring plain-language steps to Python step-implementation functions
  • Built-in formatters — plain, pretty, progress, JSON, and a rerun formatter for re-running just the failed scenarios
  • Tag expressions (via cucumber-tag-expressions) for including/excluding scenarios by tag at run time
  • Fixtures and before/after hooks (environment.py) for scenario, feature, and suite-level setup and teardown
  • Async step support for testing asyncio-based application code
  • Cucumber Expressions and parse-based step-text matchers for typed step parameters (e.g. {number:d})

Common Use Cases

  • Writing acceptance tests that product owners or QA can read and review as plain-language specifications
  • Driving BDD workflows where feature files double as living documentation of expected system behavior
  • Running selective test subsets in CI via tag expressions (e.g. --tags=@smoke)
  • Re-running only failed scenarios from a previous run using the rerun formatter to speed up debugging
  • Testing async Python services and APIs with async-aware step definitions

Under The Hood

Architecture Behave separates parsing, matching, and execution into distinct layers: parser.py turns .feature files into a model (model.py) of features, scenarios, and steps; step_registry.py holds the decorator-registered step implementations and uses matchers.py to resolve which implementation applies to a given step text (supporting parse-style, Cucumber Expression, and regex matchers); and runner.py’s Runner/Context classes drive execution, dispatching to the formatter registry (formatter/_registry.py) for output and to capture.py for stdout/log capture during scenario runs. This clean separation — model, matcher, registry, runner, formatter — means new step-matching strategies or output formats plug in without touching the execution core, and the behave.api package exposes stable interfaces (ITestRunner, formatter and step-matcher protocols) for extension.

Tech Stack Pure Python 3.10+, packaged with setuptools via pyproject.toml. Core runtime dependencies are intentionally minimal: cucumber-tag-expressions and cucumber-expressions for tag/step-text matching, parse and parse-type for lightweight typed step parameters, and tomli as a TOML backport on older interpreters. Optional extras split cleanly by concern — testing (pytest, PyHamcrest, freezegun), docs (Sphinx + furo), formatters (community HTML formatter plugins), and develop (tox, ruff, pylint, twine) — keeping the installed footprint small for end users while supporting a full contributor toolchain.

Code Quality The repository carries both tests/unit and tests/functional suites alongside a large features//issue.features/ corpus of Gherkin files that exercise behave’s own BDD engine against itself, plus behave4cmd0 helpers for CLI-level functional testing. CI (GitHub Actions) runs the test matrix across Python versions and platforms including a dedicated Windows workflow, with a CodeQL workflow for static security analysis. Ruff and pylint configurations are present in pyproject.toml for linting, and the codebase makes consistent use of custom exception types (ConfigError, AmbiguousStep) rather than swallowing errors silently.

What Makes It Unique Behave’s distinguishing choice is treating Gherkin feature files as the actual test specification rather than a thin wrapper generated from code, giving non-developers a genuinely readable artifact that stays in sync with test behavior. Its matcher abstraction supports three interchangeable step-text styles (parse expressions, Cucumber Expressions, and raw regex) side by side in the same project, and its rerun formatter and tag-expression engine give fine-grained control over large scenario suites — capabilities that go beyond a typical pytest-plugin-based BDD approach.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search