0
# pytest
1
2
A comprehensive Python testing framework that makes it easy to write simple tests while scaling to support complex functional testing for applications and libraries. pytest features detailed assertion introspection using plain assert statements, automatic test discovery, modular fixtures for managing test resources, and a rich plugin architecture with over 1300 external plugins.
3
4
## Package Information
5
6
- **Package Name**: pytest
7
- **Language**: Python
8
- **Installation**: `pip install pytest`
9
- **Version**: 8.4.2
10
- **License**: MIT
11
- **Python Compatibility**: Python 3.9+ (3.9, 3.10, 3.11, 3.12, 3.13, 3.14)
12
13
## Core Imports
14
15
```python
16
import pytest
17
```
18
19
For accessing specific functionality:
20
21
```python
22
from pytest import (
23
fixture, raises, skip, xfail, fail,
24
mark, param, approx, Config, Session
25
)
26
```
27
28
## Basic Usage
29
30
```python
31
import pytest
32
33
# Simple test function
34
def test_basic_math():
35
assert 2 + 2 == 4
36
assert 5 * 3 == 15
37
38
# Test with fixture
39
@pytest.fixture
40
def sample_data():
41
return [1, 2, 3, 4, 5]
42
43
def test_with_fixture(sample_data):
44
assert len(sample_data) == 5
45
assert sum(sample_data) == 15
46
47
# Parametrized test
48
@pytest.mark.parametrize("input,expected", [
49
(2, 4),
50
(3, 9),
51
(4, 16)
52
])
53
def test_square(input, expected):
54
assert input ** 2 == expected
55
56
# Exception testing
57
def test_exception():
58
with pytest.raises(ValueError):
59
int("invalid")
60
61
# Skipping tests
62
@pytest.mark.skip(reason="Not implemented yet")
63
def test_future_feature():
64
pass
65
66
# Expected failure
67
@pytest.mark.xfail(reason="Known bug")
68
def test_known_issue():
69
assert False
70
```
71
72
## Architecture
73
74
pytest's architecture is built around several key components:
75
76
- **Collection System**: Automatic discovery and collection of test files, classes, and functions using a tree-based collector hierarchy
77
- **Fixture System**: Dependency injection framework providing reusable test components with automatic cleanup and parametrization
78
- **Plugin Architecture**: Hook-based system enabling extensibility through 1300+ community plugins and custom implementations
79
- **Configuration Management**: Comprehensive configuration through command-line options, ini files, and programmatic access
80
- **Assertion Introspection**: Advanced assertion rewriting providing detailed failure information without custom assertion methods
81
- **Mark System**: Flexible test categorization and parametrization supporting conditional execution and metadata attachment
82
83
This design enables pytest to scale from simple unit tests to complex functional testing scenarios while maintaining ease of use and extensive customization capabilities.
84
85
## Capabilities
86
87
### Core Testing Functions
88
89
Essential functions for controlling test execution flow including skip, xfail, fail, exit, and conditional imports. These functions provide the fundamental building blocks for test control and outcome management.
90
91
```python { .api }
92
def skip(reason: str = "", *, allow_module_level: bool = False): ...
93
def xfail(reason: str = ""): ...
94
def fail(reason: str = "", pytrace: bool = True): ...
95
def exit(reason: str = "", returncode: int | None = None): ...
96
def importorskip(modname: str, minversion: str | None = None, reason: str | None = None, *, exc_type: type[ImportError] | None = None): ...
97
```
98
99
[Testing Functions](./testing-functions.md)
100
101
### Exception Handling and Assertions
102
103
Context managers and utilities for asserting exceptions, warnings, and approximate numerical comparisons. Includes comprehensive exception information and group exception handling.
104
105
```python { .api }
106
def raises(expected_exception, *, match=None, check=None) -> RaisesExc: ...
107
def warns(expected_warning, *, match=None) -> WarningsRecorder: ...
108
def deprecated_call(func=None, *args, **kwargs): ...
109
def approx(expected, rel=None, abs=None, nan_ok: bool = False): ...
110
```
111
112
[Assertions](./assertions.md)
113
114
### Fixture System and Dependency Injection
115
116
Comprehensive fixture system for managing test dependencies, setup, and teardown with support for multiple scopes, parametrization, and automatic resolution.
117
118
```python { .api }
119
def fixture(fixture_function=None, *, scope="function", params=None, autouse=False, ids=None, name=None): ...
120
121
class FixtureRequest:
122
def getfixturevalue(self, argname: str): ...
123
def applymarker(self, marker): ...
124
```
125
126
[Fixtures](./fixtures.md)
127
128
### Configuration and Plugin System
129
130
Central configuration management and plugin architecture enabling extensive customization through hooks, configuration files, and command-line options.
131
132
```python { .api }
133
class Config:
134
def getini(self, name: str): ...
135
def getoption(self, name: str): ...
136
def addinivalue_line(self, name: str, line: str): ...
137
138
class PytestPluginManager:
139
def register(self, plugin, name=None): ...
140
def unregister(self, plugin=None, name=None): ...
141
142
def hookimpl(**kwargs): ...
143
def hookspec(**kwargs): ...
144
```
145
146
[Configuration](./configuration.md)
147
148
### Test Collection and Execution
149
150
Collection tree components for test discovery, organization, and execution including nodes, collectors, items, and session management.
151
152
```python { .api }
153
class Session:
154
def collect(self): ...
155
def pytest_runtest_protocol(self, item): ...
156
157
class Function:
158
def runtest(self): ...
159
def setup(self): ...
160
def teardown(self): ...
161
162
class Metafunc:
163
def parametrize(self, argnames, argvalues, **kwargs): ...
164
```
165
166
[Test Collection](./test-collection.md)
167
168
### Test Utilities and Environment Control
169
170
Utilities for controlling test environments including monkeypatching, output capture, temporary paths, caching, and testing framework testing tools.
171
172
```python { .api }
173
class MonkeyPatch:
174
def setattr(self, target, name, value=<notset>, raising: bool = True): ...
175
def setenv(self, name: str, value: str, prepend: str | None = None): ...
176
def chdir(self, path): ...
177
178
class CaptureFixture:
179
def readouterr(self): ...
180
def disabled(self): ...
181
182
class Cache:
183
def get(self, key: str, default): ...
184
def set(self, key: str, value: object) -> None: ...
185
def mkdir(self, name: str) -> Path: ...
186
187
class Stash:
188
def __setitem__(self, key: StashKey[T], value: T) -> None: ...
189
def __getitem__(self, key: StashKey[T]) -> T: ...
190
def get(self, key: StashKey[T], default: D) -> T | D: ...
191
192
class StashKey(Generic[T]):
193
"""Type-safe key for Stash storage."""
194
195
class Pytester:
196
def makepyfile(self, **kwargs): ...
197
def runpytest(self, *args, **kwargs): ...
198
```
199
200
[Test Utilities](./test-utilities.md)
201
202
### Marks and Parametrization
203
204
Mark system for test categorization, parametrization, and metadata attachment enabling flexible test selection and data-driven testing.
205
206
```python { .api }
207
class MarkGenerator:
208
def parametrize(self, argnames, argvalues, **kwargs): ...
209
def skip(self, reason: str = ""): ...
210
def skipif(self, condition, *, reason: str = ""): ...
211
def xfail(self, condition=True, *, reason: str = "", raises=None, run: bool = True, strict: bool = False): ...
212
213
def param(*values, marks=(), id=None): ...
214
215
# Access via pytest.mark
216
mark: MarkGenerator
217
```
218
219
[Marks and Parametrization](./marks.md)
220
221
### Test Reporting and Results
222
223
Comprehensive reporting system for test execution results, collection reports, and terminal output formatting with detailed information about test outcomes.
224
225
```python { .api }
226
class TestReport:
227
def from_item_and_call(cls, item: Item, call: CallInfo[None]) -> TestReport: ...
228
229
class CollectReport:
230
def _to_json(self) -> dict[str, Any]: ...
231
232
class CallInfo(Generic[TResult]):
233
def from_call(cls, func: Callable[[], TResult], when: str, reraise=None) -> CallInfo[TResult]: ...
234
235
class TerminalReporter:
236
def write(self, content: str, *, flush: bool = False, **markup: bool) -> None: ...
237
def pytest_runtest_logreport(self, report: TestReport) -> None: ...
238
```
239
240
[Test Reporting](./reporting.md)
241
242
### Warning Types and Error Handling
243
244
Comprehensive warning type hierarchy for pytest-specific warnings including deprecation warnings, configuration warnings, and collection warnings.
245
246
```python { .api }
247
class PytestWarning(UserWarning): ...
248
class PytestDeprecationWarning(PytestWarning, DeprecationWarning): ...
249
class PytestConfigWarning(PytestWarning): ...
250
class PytestCollectionWarning(PytestWarning): ...
251
class PytestUnknownMarkWarning(PytestWarning): ...
252
```
253
254
[Warning Types](./warnings.md)
255
256
## Entry Points
257
258
```python { .api }
259
def main(
260
args: list[str] | os.PathLike[str] | None = None,
261
plugins: Sequence[str | _PluggyPlugin] | None = None,
262
) -> int | ExitCode:
263
"""
264
Main entry point for running pytest programmatically.
265
266
Performs an in-process test run with comprehensive configuration
267
and plugin management.
268
269
Parameters:
270
- args: Command line arguments. If None, uses sys.argv. Can be list
271
of strings or single PathLike object
272
- plugins: Plugin objects or names to auto-register during initialization
273
274
Returns:
275
Exit code (0 for success, non-zero for failure/errors)
276
277
Examples:
278
>>> pytest.main() # Run with default args
279
>>> pytest.main(['-v', 'tests/']) # With specific arguments
280
>>> pytest.main(['tests/'], plugins=['my_plugin']) # With plugins
281
"""
282
283
def console_main() -> int:
284
"""
285
Console script entry point for pytest command.
286
287
This is the function called when running 'pytest' from command line.
288
Not intended for programmatic use - use main() instead.
289
290
Returns:
291
Integer exit code for console applications
292
293
Note:
294
Handles BrokenPipeError gracefully and flushes stdout before returning.
295
"""
296
297
class cmdline:
298
"""Compatibility namespace for legacy pytest usage."""
299
300
main = staticmethod(main) # Provides pytest.cmdline.main() compatibility
301
```
302
303
**Usage Examples:**
304
305
```python
306
import pytest
307
from pathlib import Path
308
309
# Basic programmatic usage
310
def run_tests():
311
exit_code = pytest.main(['-v', '--tb=short'])
312
if exit_code == 0:
313
print("All tests passed!")
314
return exit_code
315
316
# With custom configuration
317
def run_specific_tests():
318
args = [
319
'tests/unit/', # Test directory
320
'-v', # Verbose output
321
'--maxfail=3', # Stop after 3 failures
322
'--tb=short', # Short traceback format
323
'-x' # Stop on first failure
324
]
325
return pytest.main(args)
326
327
# With plugins
328
def run_with_plugins():
329
return pytest.main(
330
['tests/'],
331
plugins=['pytest-html', 'pytest-cov']
332
)
333
334
# Legacy compatibility usage
335
def legacy_style():
336
return pytest.cmdline.main(['-v', 'tests/'])
337
338
# Handling results
339
def test_runner_with_handling():
340
result = pytest.main(['tests/integration/'])
341
342
if result == pytest.ExitCode.OK:
343
print("Tests passed successfully")
344
elif result == pytest.ExitCode.TESTS_FAILED:
345
print("Some tests failed")
346
elif result == pytest.ExitCode.NO_TESTS_RAN:
347
print("No tests were collected")
348
elif result == pytest.ExitCode.INTERRUPTED:
349
print("Test run was interrupted")
350
else:
351
print(f"Test run failed with exit code: {result}")
352
353
return result
354
```
355
356
## Types
357
358
```python { .api }
359
from enum import Enum
360
361
class ExitCode(Enum):
362
OK = 0
363
TESTS_FAILED = 1
364
INTERRUPTED = 2
365
INTERNAL_ERROR = 3
366
USAGE_ERROR = 4
367
NO_TESTS_RAN = 5
368
369
class UsageError(Exception):
370
"""Raised for command-line usage errors."""
371
372
class FixtureLookupError(Exception):
373
"""Raised when fixture cannot be found or resolved."""
374
```
375
376
## Built-in Fixtures
377
378
pytest provides many built-in fixtures automatically available in all tests:
379
380
```python { .api }
381
# Core configuration and request
382
def test_core_fixtures(
383
request, # FixtureRequest: Access to test context and other fixtures
384
config, # Config: pytest configuration object
385
pytestconfig, # Config: Alias for config fixture
386
):
387
pass
388
389
# Output capture
390
def test_capture_fixtures(
391
capsys, # CaptureFixture: Capture sys.stdout/stderr (text)
392
capsysbinary, # CaptureFixture: Capture sys.stdout/stderr (binary)
393
capfd, # CaptureFixture: Capture file descriptors 1/2 (text)
394
capfdbinary, # CaptureFixture: Capture file descriptors 1/2 (binary)
395
caplog, # LogCaptureFixture: Capture log messages
396
):
397
pass
398
399
# Environment modification
400
def test_environment_fixtures(
401
monkeypatch, # MonkeyPatch: Modify objects, environment, sys.path
402
):
403
pass
404
405
# Temporary paths
406
def test_temp_fixtures(
407
tmp_path, # pathlib.Path: Temporary directory (function scope)
408
tmp_path_factory, # TempPathFactory: Create additional temp directories
409
tmpdir, # py.path.local: Legacy temp directory (deprecated)
410
tmpdir_factory, # TempdirFactory: Legacy temp factory (deprecated)
411
):
412
pass
413
414
# Warning handling
415
def test_warning_fixtures(
416
recwarn, # WarningsRecorder: Record warnings during test
417
):
418
pass
419
420
# Plugin testing (requires pytest plugin)
421
def test_plugin_fixtures(
422
pytester, # Pytester: Test pytest plugins and functionality
423
testdir, # Testdir: Legacy plugin testing (deprecated)
424
):
425
pass
426
427
# Doctest integration (requires doctest plugin)
428
def test_doctest_fixtures(
429
doctest_namespace, # dict: Namespace for doctest execution
430
):
431
pass
432
```
433
434
## Version Information
435
436
```python { .api }
437
__version__: str # Current pytest version string (e.g., "8.4.2")
438
version_tuple: tuple[int, ...] # Version as tuple of integers (e.g., (8, 4, 2))
439
```
440
441
**Usage Examples:**
442
443
```python
444
import pytest
445
446
# Check pytest version
447
print(f"pytest version: {pytest.__version__}")
448
# Output: pytest version: 8.4.2
449
450
# Version tuple for programmatic comparison
451
version = pytest.version_tuple
452
if version >= (8, 0, 0):
453
print("Using modern pytest features")
454
455
# Version checking utility
456
def require_pytest_version(min_version_tuple):
457
if pytest.version_tuple < min_version_tuple:
458
raise RuntimeError(
459
f"pytest {'.'.join(map(str, min_version_tuple))} or higher required, "
460
f"found {pytest.__version__}"
461
)
462
463
# Example usage
464
require_pytest_version((7, 0, 0)) # Ensure pytest 7.0.0+
465
```