Getting started¶
This page shows the smallest useful integration first. If you want full recipes that combine several optional helpers, continue with Integration examples.
Before you start¶
You already have a Behave project with a
features/directory.You want to keep
environment.pyexplicit instead of hiding setup behind a large plugin layer.You are running on a supported Python version. See Compatibility and support.
1. Install the package¶
pip install behave-toolkit
That single install gives you:
the runtime helpers used from
features/environment.pythe
behave-toolkit-docsCLIthe Sphinx dependencies needed to build generated HTML step documentation
2. Create a minimal project layout¶
features/
behave-toolkit.yaml
environment.py
steps/
reporting_steps.py
smoke.feature
3. Create a toolkit config¶
Start with one variable, one feature-scoped resource, and one scenario-scoped path built from it:
version: 1
variables:
report_name: report.json
objects:
workspace:
factory: tempfile.TemporaryDirectory
scope: feature
cleanup: cleanup
workspace_path:
factory: pathlib.Path
scope: feature
args:
- $ref: workspace
attr: name
report_path:
factory: pathlib.Path
scope: scenario
args:
- $ref: workspace_path
- $var: report_name
factory can point to:
your own project code
an installed dependency
the Python standard library
args and kwargs can also use direct YAML values. You only need $ref and
$var when you want to reuse another managed object or a root config variable.
objects:
api_client:
factory: demo.clients.ApiClient
kwargs:
base_url: https://example.test
timeout: 30
verify_ssl: true
4. Wire features/environment.py¶
from pathlib import Path
from behave_toolkit import (
activate_feature_scope,
activate_scenario_scope,
install,
)
CONFIG_PATH = Path(__file__).with_name("behave-toolkit.yaml")
def before_all(context):
install(context, CONFIG_PATH)
def before_feature(context, feature):
del feature
activate_feature_scope(context)
def before_scenario(context, scenario):
del scenario
activate_scenario_scope(context)
This is the core runtime path:
install()loads and validates the config, attaches the manager undercontext.toolkit, and activatesglobalobjects by defaultactivate_feature_scope()creates feature-scoped objects insidebefore_featureactivate_scenario_scope()creates scenario-scoped objects insidebefore_scenariocleanup is registered with Behave so each scope tears down at the right time automatically
5. Use the injected objects from a step¶
If you do not set inject_as, the object name becomes the context attribute name.
from behave import then
@then("the report path is available")
def step_report_path_available(context):
context.report_path.write_text("ready\n", encoding="utf-8")
assert context.report_path.exists()
And a matching feature file can stay completely ordinary:
Feature: Toolkit smoke
Scenario: Use toolkit-managed objects
Then the report path is available
6. Run Behave¶
behave
At runtime the flow is:
before_all()installs the toolkit and createsglobalobjects.before_feature()creates feature-scoped objects.before_scenario()creates scenario-scoped objects.Steps use the injected instances through
context.Behave cleanup tears objects down in reverse creation order at the matching scope boundary.
7. Add optional helpers only when you need them¶
If you need… |
Helper |
When it runs |
Where it belongs |
|---|---|---|---|
Behave custom type registration from YAML |
|
import time |
top-level in |
root config variables directly in |
|
|
after |
repeated runs of one plain scenario |
|
|
after |
one persistent suite log |
|
usually |
after |
several named logs from YAML |
|
usually |
after |
8. Full hook template with optional helpers¶
Use this as the starting point when your suite grows beyond the minimal path:
from pathlib import Path
from behave_toolkit import (
activate_feature_scope,
activate_scenario_scope,
configure_parsers,
configure_test_logging,
expand_scenario_cycles,
install,
substitute_feature_variables,
)
CONFIG_PATH = Path(__file__).with_name("behave-toolkit")
# Optional: only useful when your config defines a `parsers:` section.
configure_parsers(CONFIG_PATH)
def before_all(context):
install(context, CONFIG_PATH)
# Optional: enable `{{var:name}}` placeholders in parsed feature files.
substitute_feature_variables(context)
# Optional: expand `@cycling(N)` tags on plain scenarios.
expand_scenario_cycles(context)
# Optional: keep one persistent suite log.
# Remove this line if your config does not define `test_log_path`.
context.test_logger = configure_test_logging(context.test_log_path)
def before_feature(context, feature):
del feature
activate_feature_scope(context)
def before_scenario(context, scenario):
del scenario
activate_scenario_scope(context)
If CONFIG_PATH points to a directory instead of a single file, use Path(__file__).with_name("behave-toolkit") or any other directory path that suits your project layout.
Next steps¶
Read Integration examples for copy-paste multi-feature setups.
Read Configuration model for the full schema and scope rules.
Read Lifecycle hooks for exact hook timing and cleanup behavior.
Read Troubleshooting if
install()or one of the optional helpers fails.