Architecture¶
Overview¶
behave-steplib is organised in layers:
┌──────────────────────────────────────────────────┐
│ environment.py │
│ autoload(context) / load(context, *modules) │
└───────────────────────┬──────────────────────────┘
│
┌───────────────────────▼──────────────────────────┐
│ steplib.behave │
│ Thin wrappers: autoload, load, before_all, │
│ after_scenario │
└───────────────────────┬──────────────────────────┘
│
┌───────────────────────▼──────────────────────────┐
│ steplib.core │
│ Registry · Discovery · Decorators · Metadata · │
│ i18n · Params · State · Validation · Ecosystem │
└───────────────────────┬──────────────────────────┘
│ entry points (steplib.plugins)
┌───────────────────────▼──────────────────────────┐
│ steplib.modules │
│ api · web · db · kafka · data │
│ Each module: steps · actions · context · client │
└──────────────────────────────────────────────────┘
Core package (steplib.core)¶
The core package contains the infrastructure that is independent of any specific technology:
``decorators`` — the
@stepdecorator andget_step_infoshelper. AttachesStepInfometadata to functions.``metadata`` — the
StepInfofrozen dataclass.``params`` — the
Paramdataclass, built-in type names and theTypeRegistryfor custom types.``registry`` —
StepRegistry, the central store for step metadata. Optionally registers patterns with behave.``discovery`` —
autoloadandload; discovers plugins via entry points and populates a registry.``i18n`` — pattern expansion and consistency validation for translations.
``state`` —
SteplibState, attached tocontext.steplib; holds the registry and module namespaces.``validation`` — static validation of step contracts.
``ecosystem`` — lazy integration with
behave-kit,behave-tablesandbehave-data.``exceptions`` —
SteplibError,MissingDependencyError,DuplicateStepError,StepContractError.
Module pattern (steplib.modules.*)¶
Each technology module follows the same four-file pattern:
File |
Responsibility |
|---|---|
|
Step definitions ( |
|
Pure action functions operating on the module’s context. Fully testable without behave. |
|
Per-scenario state dataclass (e.g. |
|
Backend abstraction with a |
This separation ensures that step definitions are thin, logic is testable, and backends are swappable.
Discovery flow¶
autoload(context)creates aStepRegistry.It loads every entry point in the
steplib.pluginsgroup.Each entry point’s
register(registry)function is called, which adds decorated step functions to the registry.The registry expands i18n patterns, checks for duplicates and optionally registers each pattern with behave via
behave.step(pattern)(fn).Optional
categories/backendsfilters narrow the registry.A
SteplibStateis created and returned.
Backend selection¶
Each module can support multiple backends. For example, the API module supports:
stdlib (
urllib) — default, no extra dependencies.httpx — requires the
[api]extra.requests — requires the
[requests]extra.
Backends are differentiated by the backend field on StepInfo.
When using autoload, you can select which backend to activate per
category:
autoload(context, backends={"api": "httpx"})
Without explicit filters, all backends are registered. Steps without a
backend value are always kept.
Plugin extension¶
Third-party packages can extend behave-steplib by declaring an entry point in the same group:
# pyproject.toml of a third-party package
[project.entry-points."steplib.plugins"]
mycompany = "mycompany.steps:register"
The register function receives a StepRegistry and adds steps
using the standard @step decorator:
# mycompany/steps.py
from steplib import step
@step("the invoice total is {total:f}", category="invoice")
def step_invoice_total(context, total):
...
def register(registry):
registry.add(step_invoice_total)
Once the package is installed, autoload(context) discovers it
automatically.
API reference¶
See Core API Reference for the full autodoc reference of steplib.core.registry,
steplib.core.state and steplib.core.exceptions.