0
# Fixtures
1
2
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.
3
4
## Capabilities
5
6
### Fixture Decorator
7
8
Decorator for defining reusable fixtures with setup and teardown functionality. Fixtures provide a clean way to manage resources needed by multiple steps or scenarios.
9
10
```python { .api }
11
def fixture(func=None, *, scope: str = "function", name: str = None):
12
"""
13
Decorator for defining reusable fixtures with setup/teardown.
14
15
Parameters:
16
- func: Function to be decorated (when used as @fixture)
17
- scope: str, fixture scope ("function", "scenario", "feature", "session")
18
- name: str, optional custom name for the fixture
19
20
Returns:
21
Fixture function that can be used with use_fixture()
22
"""
23
```
24
25
Usage example:
26
```python
27
@fixture(scope="session")
28
def database_connection(context):
29
# Setup: Create database connection
30
connection = create_database_connection()
31
context.db = connection
32
yield context.db
33
# Teardown: Close database connection
34
connection.close()
35
```
36
37
### Use Fixture Function
38
39
Function to explicitly use a fixture in a step or hook, enabling manual fixture management when decorators are not sufficient.
40
41
```python { .api }
42
def use_fixture(fixture_func, context, *args, **kwargs):
43
"""
44
Function to explicitly use a fixture in a step or hook.
45
46
Parameters:
47
- fixture_func: Fixture function to use
48
- context: Current execution context
49
- *args: Positional arguments to pass to fixture
50
- **kwargs: Keyword arguments to pass to fixture
51
52
Returns:
53
Fixture return value (if any)
54
"""
55
```
56
57
Usage example:
58
```python
59
# In environment.py or step file
60
def before_scenario(context, scenario):
61
use_fixture(database_connection, context)
62
use_fixture(web_browser, context, browser_type="chrome")
63
```
64
65
### Tag-based Fixture Usage
66
67
Function that applies fixtures based on tags by looking up fixtures in a registry and using them conditionally.
68
69
```python { .api }
70
def use_fixture_by_tag(tag, context, fixture_registry):
71
"""
72
Process fixture-tag to perform use_fixture() for its fixture.
73
74
Parameters:
75
- tag: str, tag name that identifies the fixture to use
76
- context: Current execution context
77
- fixture_registry: Registry containing available fixtures
78
79
Returns:
80
Fixture return value (if any)
81
"""
82
```
83
84
Usage example:
85
```python
86
# In environment.py
87
from behave.fixture import use_fixture_by_tag
88
89
# Build fixture registry
90
fixture_registry = {
91
'fixture.browser.firefox': (browser_firefox_fixture, {}),
92
'fixture.database': (database_fixture, {'timeout': 30})
93
}
94
95
def before_tag(context, tag):
96
if tag.startswith('fixture.'):
97
use_fixture_by_tag(tag, context, fixture_registry)
98
99
# In feature file:
100
# @fixture.browser.firefox
101
# Scenario: Test web functionality
102
# Given I open the application
103
```
104
105
## Fixture Scopes
106
107
Fixtures support different scopes that determine their lifecycle:
108
109
### Function Scope
110
```python
111
@fixture(scope="function")
112
def function_fixture(context):
113
# Setup before each step function
114
setup_resource()
115
yield
116
# Teardown after each step function
117
cleanup_resource()
118
```
119
120
### Scenario Scope
121
```python
122
@fixture(scope="scenario")
123
def scenario_fixture(context):
124
# Setup before each scenario
125
context.scenario_data = initialize_scenario()
126
yield context.scenario_data
127
# Teardown after each scenario
128
cleanup_scenario_data(context.scenario_data)
129
```
130
131
### Feature Scope
132
```python
133
@fixture(scope="feature")
134
def feature_fixture(context):
135
# Setup before each feature
136
context.feature_resources = setup_feature_resources()
137
yield context.feature_resources
138
# Teardown after each feature
139
cleanup_feature_resources(context.feature_resources)
140
```
141
142
### Session Scope
143
```python
144
@fixture(scope="session")
145
def session_fixture(context):
146
# Setup once before all tests
147
global_resource = initialize_global_resource()
148
context.global_resource = global_resource
149
yield global_resource
150
# Teardown once after all tests
151
cleanup_global_resource(global_resource)
152
```
153
154
## Fixture Registry
155
156
The fixture system includes a registry for managing and organizing fixtures:
157
158
```python { .api }
159
class FixtureRegistry:
160
"""
161
Registry for managing fixture definitions and their metadata.
162
163
Methods:
164
- register_fixture(fixture_func, name=None, scope="function"): Register a fixture
165
- get_fixture(name): Retrieve a fixture by name
166
- get_fixtures_by_scope(scope): Get all fixtures for a specific scope
167
- clear(): Clear all registered fixtures
168
"""
169
```
170
171
## Common Fixture Patterns
172
173
### Database Fixture
174
```python
175
@fixture(scope="feature")
176
def database(context):
177
# Setup test database
178
db = create_test_database()
179
context.db = db
180
# Load test data
181
load_test_data(db)
182
yield db
183
# Cleanup
184
drop_test_database(db)
185
```
186
187
### Web Browser Fixture
188
```python
189
@fixture(scope="scenario")
190
def browser(context):
191
# Setup browser
192
from selenium import webdriver
193
driver = webdriver.Chrome()
194
context.browser = driver
195
yield driver
196
# Cleanup
197
driver.quit()
198
```
199
200
### API Client Fixture
201
```python
202
@fixture(scope="session")
203
def api_client(context):
204
# Setup API client
205
import requests
206
session = requests.Session()
207
session.headers.update({'Authorization': 'Bearer test-token'})
208
context.api_client = session
209
yield session
210
# Cleanup
211
session.close()
212
```
213
214
### Temporary File Fixture
215
```python
216
@fixture(scope="function")
217
def temp_file(context):
218
import tempfile
219
import os
220
# Create temporary file
221
fd, path = tempfile.mkstemp()
222
context.temp_file_path = path
223
yield path
224
# Cleanup
225
os.close(fd)
226
os.unlink(path)
227
```
228
229
## Fixture Integration with Hooks
230
231
Fixtures work seamlessly with behave's hook system:
232
233
```python
234
# In environment.py
235
def before_feature(context, feature):
236
if 'database' in feature.tags:
237
use_fixture(database_fixture, context)
238
239
def before_scenario(context, scenario):
240
if 'browser' in scenario.tags:
241
use_fixture(browser_fixture, context)
242
```