Behavior-driven development testing framework for Python using Gherkin syntax
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Reusable setup and teardown functionality for managing test state, database connections, browser instances, and other resources. Fixtures can be scoped to functions, scenarios, features, or the entire test session.
Decorator for defining reusable fixtures with setup and teardown functionality. Fixtures provide a clean way to manage resources needed by multiple steps or scenarios.
def fixture(func=None, *, scope: str = "function", name: str = None):
"""
Decorator for defining reusable fixtures with setup/teardown.
Parameters:
- func: Function to be decorated (when used as @fixture)
- scope: str, fixture scope ("function", "scenario", "feature", "session")
- name: str, optional custom name for the fixture
Returns:
Fixture function that can be used with use_fixture()
"""Usage example:
@fixture(scope="session")
def database_connection(context):
# Setup: Create database connection
connection = create_database_connection()
context.db = connection
yield context.db
# Teardown: Close database connection
connection.close()Function to explicitly use a fixture in a step or hook, enabling manual fixture management when decorators are not sufficient.
def use_fixture(fixture_func, context, *args, **kwargs):
"""
Function to explicitly use a fixture in a step or hook.
Parameters:
- fixture_func: Fixture function to use
- context: Current execution context
- *args: Positional arguments to pass to fixture
- **kwargs: Keyword arguments to pass to fixture
Returns:
Fixture return value (if any)
"""Usage example:
# In environment.py or step file
def before_scenario(context, scenario):
use_fixture(database_connection, context)
use_fixture(web_browser, context, browser_type="chrome")Function that applies fixtures based on tags by looking up fixtures in a registry and using them conditionally.
def use_fixture_by_tag(tag, context, fixture_registry):
"""
Process fixture-tag to perform use_fixture() for its fixture.
Parameters:
- tag: str, tag name that identifies the fixture to use
- context: Current execution context
- fixture_registry: Registry containing available fixtures
Returns:
Fixture return value (if any)
"""Usage example:
# In environment.py
from behave.fixture import use_fixture_by_tag
# Build fixture registry
fixture_registry = {
'fixture.browser.firefox': (browser_firefox_fixture, {}),
'fixture.database': (database_fixture, {'timeout': 30})
}
def before_tag(context, tag):
if tag.startswith('fixture.'):
use_fixture_by_tag(tag, context, fixture_registry)
# In feature file:
# @fixture.browser.firefox
# Scenario: Test web functionality
# Given I open the applicationFixtures support different scopes that determine their lifecycle:
@fixture(scope="function")
def function_fixture(context):
# Setup before each step function
setup_resource()
yield
# Teardown after each step function
cleanup_resource()@fixture(scope="scenario")
def scenario_fixture(context):
# Setup before each scenario
context.scenario_data = initialize_scenario()
yield context.scenario_data
# Teardown after each scenario
cleanup_scenario_data(context.scenario_data)@fixture(scope="feature")
def feature_fixture(context):
# Setup before each feature
context.feature_resources = setup_feature_resources()
yield context.feature_resources
# Teardown after each feature
cleanup_feature_resources(context.feature_resources)@fixture(scope="session")
def session_fixture(context):
# Setup once before all tests
global_resource = initialize_global_resource()
context.global_resource = global_resource
yield global_resource
# Teardown once after all tests
cleanup_global_resource(global_resource)The fixture system includes a registry for managing and organizing fixtures:
class FixtureRegistry:
"""
Registry for managing fixture definitions and their metadata.
Methods:
- register_fixture(fixture_func, name=None, scope="function"): Register a fixture
- get_fixture(name): Retrieve a fixture by name
- get_fixtures_by_scope(scope): Get all fixtures for a specific scope
- clear(): Clear all registered fixtures
"""@fixture(scope="feature")
def database(context):
# Setup test database
db = create_test_database()
context.db = db
# Load test data
load_test_data(db)
yield db
# Cleanup
drop_test_database(db)@fixture(scope="scenario")
def browser(context):
# Setup browser
from selenium import webdriver
driver = webdriver.Chrome()
context.browser = driver
yield driver
# Cleanup
driver.quit()@fixture(scope="session")
def api_client(context):
# Setup API client
import requests
session = requests.Session()
session.headers.update({'Authorization': 'Bearer test-token'})
context.api_client = session
yield session
# Cleanup
session.close()@fixture(scope="function")
def temp_file(context):
import tempfile
import os
# Create temporary file
fd, path = tempfile.mkstemp()
context.temp_file_path = path
yield path
# Cleanup
os.close(fd)
os.unlink(path)Fixtures work seamlessly with behave's hook system:
# In environment.py
def before_feature(context, feature):
if 'database' in feature.tags:
use_fixture(database_fixture, context)
def before_scenario(context, scenario):
if 'browser' in scenario.tags:
use_fixture(browser_fixture, context)Install with Tessl CLI
npx tessl i tessl/pypi-behave