0
# Plugin Integration
1
2
pytest-cov integrates deeply with pytest's plugin system through hooks, fixtures, and configuration. The plugin automatically registers when installed and provides seamless coverage measurement throughout the pytest lifecycle.
3
4
## Capabilities
5
6
### Plugin Registration and Configuration
7
8
pytest-cov registers as a pytest11 plugin through setuptools entry points, making it automatically available when installed.
9
10
```python { .api }
11
def pytest_addoption(parser):
12
"""
13
Add coverage-related command-line options to pytest.
14
15
Creates a 'cov' option group with all coverage control options including
16
--cov, --cov-report, --cov-config, --no-cov, --cov-fail-under, etc.
17
18
Args:
19
parser: pytest argument parser
20
"""
21
22
def pytest_configure(config):
23
"""
24
Register pytest markers for coverage control.
25
26
Adds the 'no_cover' marker that can be used to exclude specific tests
27
from coverage measurement.
28
29
Args:
30
config: pytest configuration object
31
"""
32
```
33
34
**Usage Examples:**
35
36
```python
37
# The plugin automatically adds these options to pytest
38
pytest --help # Shows all --cov-* options
39
40
# Marker usage in tests
41
@pytest.mark.no_cover
42
def test_excluded_from_coverage():
43
pass
44
```
45
46
### Early Initialization
47
48
Controls early plugin initialization and handles configuration conflicts.
49
50
```python { .api }
51
def pytest_load_initial_conftests(early_config, parser, args):
52
"""
53
Early plugin initialization hook.
54
55
Processes command-line arguments early to detect configuration conflicts
56
(like --no-cov combined with --cov options) and initializes the coverage
57
plugin if coverage sources are specified.
58
59
Args:
60
early_config: Early pytest configuration
61
parser: Argument parser
62
args: Command-line arguments
63
"""
64
```
65
66
This hook ensures that coverage measurement begins as early as possible in the pytest lifecycle, before most other plugins and test collection occurs.
67
68
### Core Plugin Class
69
70
The main plugin class that orchestrates coverage measurement across different testing scenarios.
71
72
```python { .api }
73
class CovPlugin:
74
"""
75
Main coverage plugin that delegates to different controllers based on testing mode.
76
77
Automatically detects whether running in single-process, distributed master,
78
or distributed worker mode and uses the appropriate coverage controller.
79
"""
80
81
def __init__(self, options: argparse.Namespace, pluginmanager, start: bool = True, no_cov_should_warn: bool = False):
82
"""
83
Initialize the coverage plugin.
84
85
Args:
86
options: Parsed command-line options
87
pluginmanager: pytest plugin manager
88
start: Whether to start coverage immediately
89
no_cov_should_warn: Whether to warn about --no-cov conflicts
90
"""
91
92
def start(self, controller_cls: type, config=None, nodeid: Optional[str] = None):
93
"""
94
Start coverage measurement with specified controller.
95
96
Args:
97
controller_cls: Controller class (Central, DistMaster, or DistWorker)
98
config: pytest configuration object
99
nodeid: Node identifier for distributed testing
100
"""
101
```
102
103
### Session Lifecycle Hooks
104
105
Hooks that integrate with pytest's session lifecycle for comprehensive coverage control.
106
107
```python { .api }
108
def pytest_sessionstart(self, session):
109
"""
110
Initialize coverage at session start.
111
112
Determines the appropriate coverage controller based on testing mode:
113
- DistWorker for pytest-xdist worker processes
114
- Central for single-process testing
115
- Uses existing controller if already started
116
117
Args:
118
session: pytest session object
119
"""
120
121
def pytest_runtestloop(self, session):
122
"""
123
Wrap the main test execution loop.
124
125
Configures warning filters for coverage-related warnings and handles
126
coverage finalization and reporting after test execution completes.
127
Sets up proper warning handling for ResourceWarning, PytestCovWarning,
128
and CoverageWarning.
129
130
Args:
131
session: pytest session object
132
133
Returns:
134
Test execution result
135
"""
136
137
def pytest_terminal_summary(self, terminalreporter):
138
"""
139
Display coverage summary in terminal output.
140
141
Formats and displays coverage reports and threshold checking results.
142
Handles warning display for disabled coverage and report generation failures.
143
144
Args:
145
terminalreporter: pytest terminal reporter
146
"""
147
```
148
149
### Test Lifecycle Hooks
150
151
Hooks that control coverage measurement at the individual test level.
152
153
```python { .api }
154
def pytest_runtest_setup(self, item):
155
"""
156
Handle test setup for coverage measurement.
157
158
Initializes subprocess coverage if the test is running in a different
159
process than the main session (handles forked test scenarios).
160
161
Args:
162
item: pytest test item
163
"""
164
165
def pytest_runtest_teardown(self, item):
166
"""
167
Handle test teardown for coverage cleanup.
168
169
Cleans up any subprocess coverage data collection initiated during
170
test setup.
171
172
Args:
173
item: pytest test item
174
"""
175
176
def pytest_runtest_call(self, item):
177
"""
178
Control coverage during test execution.
179
180
Pauses coverage measurement for tests marked with 'no_cover' marker
181
or tests that use the 'no_cover' fixture, then resumes coverage
182
after test completion.
183
184
Args:
185
item: pytest test item
186
"""
187
```
188
189
### Distributed Testing Integration
190
191
Optional hooks for integration with pytest-xdist distributed testing.
192
193
```python { .api }
194
def pytest_configure_node(self, node):
195
"""
196
Configure a distributed testing node.
197
198
Sends configuration information to worker nodes including master host,
199
directory paths, and rsync roots for proper coverage data collection
200
and file path mapping.
201
202
Args:
203
node: pytest-xdist node object
204
205
Note:
206
This hook is marked as optional and only used when pytest-xdist is installed.
207
"""
208
209
def pytest_testnodedown(self, node, error):
210
"""
211
Handle distributed testing node shutdown.
212
213
Collects coverage data from worker nodes and integrates it with master
214
coverage data. Handles both collocated and remote worker scenarios with
215
appropriate data file management and path mapping.
216
217
Args:
218
node: pytest-xdist node object
219
error: Any error that occurred during node shutdown
220
221
Note:
222
This hook is marked as optional and only used when pytest-xdist is installed.
223
"""
224
```
225
226
### Context Management Plugin
227
228
Specialized plugin for managing coverage contexts during test execution.
229
230
```python { .api }
231
class TestContextPlugin:
232
"""
233
Plugin for managing coverage contexts during test execution.
234
235
Provides per-test context switching when --cov-context=test is used,
236
enabling detailed tracking of coverage attribution to specific tests.
237
"""
238
239
def __init__(self, cov_controller):
240
"""
241
Initialize context plugin.
242
243
Args:
244
cov_controller: Coverage controller instance
245
"""
246
247
def pytest_runtest_setup(self, item):
248
"""Switch coverage context for test setup phase."""
249
250
def pytest_runtest_call(self, item):
251
"""Switch coverage context for test execution phase."""
252
253
def pytest_runtest_teardown(self, item):
254
"""Switch coverage context for test teardown phase."""
255
256
def switch_context(self, item, when: str):
257
"""
258
Switch coverage context and update environment.
259
260
Args:
261
item: pytest test item
262
when: Phase of test execution ('setup', 'run', 'teardown')
263
"""
264
```
265
266
## Internal Helper Functions
267
268
Utility functions that support plugin functionality.
269
270
```python { .api }
271
def _is_worker(self, session) -> bool:
272
"""
273
Determine if running in a pytest-xdist worker process.
274
275
Args:
276
session: pytest session object
277
278
Returns:
279
bool: True if running in worker process
280
"""
281
282
def _should_report(self) -> bool:
283
"""
284
Determine if coverage reports should be generated.
285
286
Returns:
287
bool: True if reporting is needed and conditions are met
288
"""
289
290
def write_heading(self, terminalreporter):
291
"""
292
Write coverage section heading to terminal output.
293
294
Args:
295
terminalreporter: pytest terminal reporter
296
"""
297
```