The Swiss-army knife for Behave — soft assertions, typed context, conditional skip, env management, fixtures and more.
Project description
behave-kit
The Swiss-army knife for Behave — soft assertions, typed context, conditional skip, environment management, fixtures and more.
Why behave-kit?
Behave is great for BDD, but real test suites need more than Given/When/Then. You need to:
- Collect multiple assertion failures without stopping at the first one
- Skip steps based on environment, OS, or missing dependencies
- Read environment variables with type conversion and validation
- Load test data from CSV, JSON, YAML, or Excel files
- Manage fixtures with automatic setup/teardown by tag
- Get IDE autocompletion for context attributes
- Debug failures with automatic context dumps
behave-kit provides all of these as independent, opt-in utilities — no monkey-patching, no breaking changes.
Installation
pip install behave-kit
With optional extras:
pip install "behave-kit[yaml,excel,dotenv]"
| Extra | Provides | Dependency |
|---|---|---|
yaml |
YAML data loading | pyyaml>=6.0 |
excel |
XLSX data loading | openpyxl>=3.1 |
dotenv |
.env file loading |
python-dotenv>=1.0 |
docs |
Sphinx documentation build | sphinx, furo, myst-parser |
dev |
Development tools | pytest, ruff, mypy, build, pre-commit |
Quickstart
Level 1 — Automatic wiring
Add two lines to your environment.py and every feature is wired automatically:
from behave_kit import setup, teardown
def before_all(context):
setup(context, env="staging")
def after_scenario(context, scenario):
teardown(context)
Level 2 — Cherry-pick
Import only what you need:
from behave_kit import assert_soft, env, load_data
@then("the response should be valid")
def step(context):
assert_soft(context.response.status_code == 200)
api_key = env("API_KEY", required=True)
users = load_data("tests/data/users.csv")
Level 3 — Namespace
import behave_kit as bk
@then("the response should be valid")
def step(context):
bk.assert_soft(context.response.status_code == 200)
Features
Soft assertions
Collect multiple failures and report them all at once:
from behave_kit import assert_soft
assert_soft(response.status_code == 200)
assert_soft(response.body["count"] > 0)
assert_soft("error" not in response.body)
# All failures reported together at teardown
TypedContext
Schema-validated proxy with IDE autocompletion and mypy support:
from behave_kit import TypedContext
class MySchema:
driver: str
base_url: str
ctx = TypedContext(context, MySchema)
ctx.setup(driver="chrome", base_url="https://test.com")
print(ctx.driver) # IDE autocompletion works
Conditional skip
Skip steps by environment, OS, or missing dependency:
from behave_kit import skip_if_env, skip_if_no_browser, skip_on_os, skip_if_missing
@skip_if_env("production")
@when("I run the staging-only step")
def step(context): ...
@skip_if_no_browser
@when("I open the browser")
def step(context): ...
@skip_on_os("windows")
@when("I run the unix-only step")
def step(context): ...
@skip_if_missing("selenium")
@when("I use selenium")
def step(context): ...
Environment variables
Typed reads with defaults, validation, and config file fallback:
from behave_kit import env
api_key = env("API_KEY", required=True) # str
timeout = env("TIMEOUT", var_type=int, default=30) # int
debug = env("DEBUG", var_type=bool, default=False) # bool
Data loading
Single API for CSV, JSON, YAML, and Excel:
from behave_kit import load_data
users = load_data("tests/data/users.csv") # list[dict]
config = load_data("tests/data/config.json") # dict
sheet = load_data("tests/data/sheet.xlsx") # list[dict] (requires [excel])
Fixtures
Tag-based setup/teardown with dependency resolution:
from behave_kit import fixture
@fixture("browser")
def browser_fixture(context):
def setup(ctx):
ctx.browser = start_browser()
def teardown(ctx):
ctx.browser.quit()
return (setup, teardown)
@fixture("database", requires="browser")
def database_fixture(context):
...
Context dump
Automatic context snapshot on scenario failure for easier debugging:
from behave_kit import dump_context_on_failure
# Wired automatically by setup(), or call manually
Step suggestions
"Did you mean?" hints for undefined steps:
from behave_kit import setup_suggestions
# Wired automatically by setup()
Scoped attributes
Automatic cleanup of context attributes per scenario:
from behave_kit import scoped
@scoped("driver")
@when("I start the driver")
def step(context):
context.driver = start_driver()
# "driver" is automatically deleted after the scenario
Conditional steps
Run a step only when a condition holds:
from behave_kit import when_if
@when_if(lambda ctx: ctx.config.env == "staging")
@when("I run the staging-only step")
def step(context): ...
Parameter types
Register custom Behave parameter types:
from behave_kit import parameter_type
@parameter_type("User", r"[\w.]+@[\w.]+\.[a-z]+")
def parse_user(text):
return User(name=text)
Documentation
Full documentation is available at mathiaspaulenko.github.io/behave-kit.
To build docs locally:
pip install "behave-kit[docs]"
cd docs && sphinx-build -b html . _build/html
Development
See CONTRIBUTING.md for development setup, coding standards, and contribution guidelines.
License
MIT — see 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_kit-1.1.1.tar.gz.
File metadata
- Download URL: behave_kit-1.1.1.tar.gz
- Upload date:
- Size: 66.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
174365efb10ce1b20093cd892c83ebeccf9bc5d050b16267f9124c78d61141d3
|
|
| MD5 |
5f64052702dc67cb7b445b22d9631301
|
|
| BLAKE2b-256 |
8df98b741dce6f20bfe3460c779336587cfb057213998f7722dd2280aa33b488
|
Provenance
The following attestation bundles were made for behave_kit-1.1.1.tar.gz:
Publisher:
release.yml on MathiasPaulenko/behave-kit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
behave_kit-1.1.1.tar.gz -
Subject digest:
174365efb10ce1b20093cd892c83ebeccf9bc5d050b16267f9124c78d61141d3 - Sigstore transparency entry: 2209522194
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/behave-kit@e8941e04d6795466fc9f28dde4bb2430de6f1fb3 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8941e04d6795466fc9f28dde4bb2430de6f1fb3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file behave_kit-1.1.1-py3-none-any.whl.
File metadata
- Download URL: behave_kit-1.1.1-py3-none-any.whl
- Upload date:
- Size: 42.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9a551ab4626437ba9557ff9f0c1b8fa175b81848cd22dc8b7b3ec1624fe35cd
|
|
| MD5 |
42fbbf24954cd0b37439674a9df46421
|
|
| BLAKE2b-256 |
17b5eae8fb61cbd606ea62388d5b66a08ba9a09606545e708d559d24fbae82b2
|
Provenance
The following attestation bundles were made for behave_kit-1.1.1-py3-none-any.whl:
Publisher:
release.yml on MathiasPaulenko/behave-kit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
behave_kit-1.1.1-py3-none-any.whl -
Subject digest:
a9a551ab4626437ba9557ff9f0c1b8fa175b81848cd22dc8b7b3ec1624fe35cd - Sigstore transparency entry: 2209522230
- Sigstore integration time:
-
Permalink:
MathiasPaulenko/behave-kit@e8941e04d6795466fc9f28dde4bb2430de6f1fb3 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/MathiasPaulenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e8941e04d6795466fc9f28dde4bb2430de6f1fb3 -
Trigger Event:
push
-
Statement type: