Passing context across steps with pytest-bdd

Ivan Georgiev
2 min readDec 26, 2021

Behave framework uses generic catch-them-all context to maintain state across test steps. Many newcomers to the pytest and pytest-bdd world are wondering how to do the same with pytest-bdd. Read further to find how.

Context is like black box. Use it with caution

Pytest-bdd is a pytest plugin. This makes it possible to use pytest fixture to maintain state across test steps as context. Below is an example scenario and steps implementation which uses a dictionary as generic context to pass across steps.

context.feature

Feature: Context with pytest-bdd
Scenario: Context is passed
When I run a step which updates the context
Then context is updated

test_context.py

import pytest
from pytest_bdd import scenarios, when, then
scenarios("./context.feature")@pytest.fixture(scope="function")
def ctx():
yield {}
@when("I run a step which updates the context")
def when_update_context(ctx):
ctx["updated"] = True
@then("context is updated")
def context_updated(ctx):
assert "updated" in ctx
assert ctx["updated"] is True

Warning! Use contexts wisely and with caution

Although passing context between steps is easy, generally it should be considered code smell:

  • Increases coupling between steps
  • Makes dependencies implicit and obscure

It is recommended to use explicit fixtures instead. Initialize necessary fixtures by given steps. Pass the fixtures further to other steps as explicit pytest fixtures.

If you want to learn more about behavior driven development with Python and pytest-bdd, check-out my article Behavior Driven Development with pytest-bdd.

--

--