# Lifecycle hooks [<- Back to home](index.md) ## Supported scopes | Scope | Typical hook | Lifetime | | --- | --- | --- | | `global` | `before_all` | Entire test run | | `feature` | `before_feature` | One feature file | | `scenario` | `before_scenario` | One scenario | The current release only supports these three runtime scopes. ## Public hook helpers | Helper | Typical call site | Purpose | | --- | --- | --- | | `expand_scenario_cycles(context)` | `before_all` | Expand tagged plain scenarios that use `@cycling(N)` before any feature runs. | | `install(context, config_path, ...)` | `before_all` | Load the config, validate it, attach the manager, and optionally activate global objects. | | `configure_test_logging(log_path, ...)` | usually `before_all` | Configure one dedicated test-run logger writing to a chosen file, with optional console output. | | `configure_loggers(context, ...)` | usually `before_all` | Materialize loggers from the optional YAML `logging:` section. | | `activate_global_scope(context, ...)` | `before_all` | Explicitly activate global objects when you disable `activate_global`. | | `activate_feature_scope(context, ...)` | `before_feature` | Create and expose feature-scoped objects. | | `activate_scenario_scope(context, ...)` | `before_scenario` | Create and expose scenario-scoped objects. | | `activate_scope(context, scope, ...)` | advanced usage | Generic scope activation wrapper. | `activate_scope(context, Scope.FEATURE)` and friends all route through the same generic activation logic. The dedicated helpers are just the friendlier, hook-specific wrappers. ## Global scope behavior `global` is the run-wide scope: - with the default flow, `install(context, ...)` activates it from `before_all()` - with the explicit flow, call `install(..., activate_global=False)` and then `activate_global_scope(context)` from `before_all()` - cleanup runs automatically when Behave closes the test-run layer at the very end of the suite That makes `global` a good fit for shared clients, suite-wide temp locations, or other resources that should be created once and destroyed once. ## Cleanup model The toolkit relies on Behave's cleanup layers through `context.add_cleanup(...)` so that cleanup runs with the same scope boundaries as object creation. - objects are created lazily within the requested scope - cleanup is registered immediately after creation - teardown runs in reverse order of creation inside the Behave layer ## Manager inspection By default the toolkit manager is attached to `context.toolkit`. Useful methods include: | Method | Purpose | | --- | --- | | `context.toolkit.list_objects()` | List configured object names. | | `context.toolkit.list_loggers()` | List configured logger names. | | `context.toolkit.spec(name)` | Inspect the normalized spec for one object. | | `context.toolkit.instance(name)` | Fetch an already-active object instance. | | `context.toolkit.logger(name)` | Fetch an active configured logger. | | `context.toolkit.objects_for_scope(scope)` | List the specs assigned to a scope. | | `context.toolkit.active_objects(scope)` | Inspect currently active instances by scope. | For logger setup, the recommended default is the smaller `configure_test_logging(log_path)` helper when you just want one persistent `test-run.log`-style file. Use `configure_loggers(context)` only when you want multiple named loggers defined in YAML. When you do use `configure_loggers(context)`, call it after global objects are active. With the default `install(context, config_path)` that means “right after install”; if you opt into `activate_global=False`, call `activate_global_scope(context)` first. ## Integration failures Two public error types are especially relevant while wiring hooks: - `ConfigError` for YAML loading, validation, references, and import problems - `IntegrationError` for namespace collisions, missing installation, or calling activation helpers in the wrong hook order ```{note} If you call `activate_feature_scope()` or `activate_scenario_scope()` before `install()`, the error message explicitly tells you to wire `install(context, ...)` from `before_all`. ```