Skip to main content
Resource is Merit’s dependency injection system that provides reusable components to merit functions. It follows pytest’s fixture pattern, matching function parameters by name to automatically inject dependencies. Using @merit.resource enables:
  • Injecting dependencies into merit functions without explicit instantiation
  • Sharing expensive setup across multiple merits (database connections, API clients)
  • Automatic teardown and cleanup with generator syntax
  • Scoping lifecycles at case, suite, or session level
  • Stacking resources to build complex dependency hierarchies
Metric and SUT also use the Resource API.

Basic Usage

The most common pattern is to define a resource function and inject it into your merit tests by parameter name.
Merit automatically detects the api_client parameter, calls the resource function, and injects the result. No explicit wiring needed.

Generator Pattern for Setup and Teardown

Resources can use generator syntax to define setup and teardown logic, similar to pytest fixtures with yield.
The code after yield runs automatically after the merit completes, ensuring cleanup even if the merit fails.

Async Resources

Resources support async functions and async generators for asynchronous setup/teardown.
Merit automatically detects async resources and awaits them appropriately.

Scopes: Case, Suite, Session

Resources can be scoped to control their lifecycle and determine how instances are shared across merits.
Available scopes:
  • "case": New instance per parametrized merit case (default)
  • "suite": One instance per merit file/module
  • "session": One instance for entire merit run

Stacking Resources: Dependency Injection

Resources can depend on other resources by declaring them as parameters. This enables building complex dependency graphs and composing reusable components.
This creates a dependency chain:
Merit resolves dependencies automatically, respecting scopes: config is created once per session, http_client once per suite, and authenticated_client fresh for each merit case.

Lifecycle Hooks

Resources support three optional hooks for advanced control:
Hook execution order:
  1. on_resolve: Called once when resource is first created (after factory runs, before caching)
  2. on_injection: Called every time the resource is injected into a merit (even from cache)
  3. on_teardown: Called after generator teardown code runs (post-yield)
Hooks can be sync or async functions and can modify the resource value:

Recommendations

1. Use resources for expensive or stateful setup

Resources shine when setup is costly or requires cleanup. For simple values, just use function parameters directly. Don’t do this:
Do this:

2. Use generators for resources requiring cleanup

Any resource that allocates external resources (files, connections, processes) should use the generator pattern to ensure cleanup. Don’t do this:
Do this:

3. Scope resources appropriately for performance and isolation

Choose scope based on cost of creation and whether state should be shared. Wider scopes improve performance but reduce isolation.

4. Stack resources to build reusable components

Break complex setup into smaller resources that depend on each other. This improves reusability and makes merit code more maintainable. Don’t do this:
Do this:

5. Use hooks for cross-cutting concerns

Lifecycle hooks enable instrumentation, monitoring, and side effects without cluttering merit logic.
Hooks are also useful for refreshing tokens, starting transactions, or resetting state between injections.