Skip to main content

behave-retry

CI Docs PyPI Python License Coverage

Automatic retry for failed Behave scenarios — real re-execution, tag overrides, exception filtering, and flakiness stats.

Full documentation →

Why?

Behave has no built-in retry. When a scenario fails due to flakiness (timing, network, race conditions), there's no way to re-run it automatically. Cucumber has --retry natively. Behave doesn't.

behave-retry fills that gap by patching Behave's Scenario.run to re-execute failed scenarios automatically — with tag overrides, exception filtering, and flakiness stats.

Comparison

Feature behave-retry Cucumber --retry pytest-rerunfailures
Per-scenario retry override @retry:N tag @retry N tag @pytest.mark.flaky(reruns=N)
Exception filtering retry_on=[...] No only_rerun/reruns_except
Tag filtering retry_tags=["@flaky"] No No
Global retry budget max_total_retries No No
Exponential backoff retry_delay + backoff_factor No reruns_delay (fixed)
On-retry callback on_retry No No
Retry stats Human + JSON No No
Scenario Outline support Per-example keys N/A N/A
Runtime dependencies Zero — pytest plugin

Install

pip install behave-retry

Quick start

# environment.py
from behave_retry import setup_retry, after_scenario_hook, retry_report

def before_all(context):
    setup_retry(context, max_retries=3)

def after_scenario(context, scenario):
    after_scenario_hook(context, scenario)

def after_all(context):
    print(retry_report(context))

That's it. Failed scenarios will now be re-executed up to 3 times automatically.

Features

  • Global retry — retry all failed scenarios up to N times
  • Tag-filtered retry — only retry scenarios with specific tags (@flaky)
  • Exception-filtered retry — only retry on specific exception types or string names
  • Per-scenario override — @retry:N tag overrides global config
  • Feature-level tags — @retry:N on Feature inherits to scenarios
  • Global retry budget — limit total retries across all scenarios
  • Retry delay and backoff — configurable delay with exponential backoff
  • On-retry callback — custom logic before each retry (cleanup, screenshots, etc.)
  • Flakiness stats — human-readable summary and machine-readable JSON export
  • Scenario Outline support — unique keys per example, independent retry counts
  • Environment variables — control retry from behave-runner or CI without touching code
  • Logging — via standard logging module under behave_retry logger
  • Type-safe — py.typed marker included, full type hints, mypy clean

Configuration

setup_retry(
    context,
    max_retries=3,              # max retries per scenario
    retry_tags=["@flaky"],      # only retry tagged scenarios
    retry_on=[AssertionError, TimeoutError],  # only retry these exceptions
    retry_delay=2.0,            # 2s delay before first retry
    backoff_factor=2.0,         # double delay each retry (2s, 4s, 8s)
    on_retry=lambda ctx, sc, att, exc: print(f"Retry {sc.name} #{att}: {exc}"),
    max_total_retries=20,       # stop after 20 total retries across all scenarios
)

See the configuration guide for full details.

Environment variables

You can control retry behavior via environment variables. This is useful when running tests through behave-runner, CI pipelines, or any orchestration tool that passes configuration through the environment.

# environment.py — no hard-coded values
def before_all(context):
    setup_retry(context)
# CLI
BEHAVE_RETRY_MAX_RETRIES=3 BEHAVE_RETRY_DELAY=2.0 BEHAVE_RETRY_BACKOFF=2.0 behave
Env var Type Default Maps to
BEHAVE_RETRY_MAX_RETRIES int 0 max_retries
BEHAVE_RETRY_DELAY float 0.0 retry_delay
BEHAVE_RETRY_BACKOFF float 1.0 backoff_factor
BEHAVE_RETRY_MAX_TOTAL int None max_total_retries

Explicit arguments always win. If you call setup_retry(context, max_retries=5), the env var is ignored.

How it works

  1. setup_retry patches behave.model.Scenario.run with a retry-aware wrapper.
  2. When a scenario fails, the wrapper checks:
    • Does the scenario have retries remaining? (global max_retries or @retry:N override)
    • Is the scenario tagged for retry? (if retry_tags is set)
    • Is the exception type eligible? (if retry_on is set)
    • Is the global retry budget exhausted? (if max_total_retries is set)
  3. If all checks pass, it resets the scenario state and re-runs it.
  4. Stats are tracked and available via retry_report() or stats.to_dict().

Note: before_scenario/after_scenario hooks run per attempt, and formatter output only shows the final attempt. See Known limitations.

Documentation

Section Description
Installation Install from PyPI or source
Quick start Three-step setup guide
Features Complete feature walkthrough with examples
Configuration All parameters, validation, and precedence rules
Examples Real-world recipes for common use cases
API reference Full autodoc API
Changelog Version history

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

License

MIT — Copyright (c) 2026 Mathias Paulenko

Metadata

Release files for behave-retry 1.9.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-retry 1.9.0
File Size Uploaded
behave_retry-1.9.0.tar.gz 53.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for behave-retry 1.9.0
File Interpreter ABI Platform
behave_retry-1.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 69.6 kB

Release files / behave_retry-1.9.0.tar.gz

Download URL behave_retry-1.9.0.tar.gz
Size 53.4 kB
Tags Source
SHA-256 checksum
How to use checksums
21809c2c0a1a62e4889168ee5287f8155e29550c21112c4114fb35b46d993f8f
BLAKE2b-256 checksum
How to use checksums
467d8b3522ea8f43fc182bf00a8b9e85d61b3a1826e6e1911739c2e8bbe6221a
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 5, 2026.

Transparency log

Release files / behave_retry-1.9.0-py3-none-any.whl

Download URL behave_retry-1.9.0-py3-none-any.whl
Size 16.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0bfd6dbf70fbc42d4302b0ed29bc5b061d4a30acbea32111831f81c99618af35
BLAKE2b-256 checksum
How to use checksums
e978c39ce93709dad06ca3e282b3bf6cc9f981d2d80ca9b0d72d4486cfc563ed
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 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.9.0 This release

2 release files

1.8.4

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.2

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