fixtures.rst
Overview
The [fixtures.rst](/projects/286/67203) file is a comprehensive reference document for **pytest fixtures**, a core feature of the pytest testing framework. It explains the purpose, behavior, and usage of fixtures, which are reusable components that help set up and tear down test environments in a modular and maintainable way.
This document covers:
The built-in fixtures provided by pytest.
How fixture availability and scope are determined.
Sharing fixtures across multiple test files using
conftest.py.Integration of fixtures from third-party plugins.
The rules and algorithms pytest uses to determine fixture instantiation order.
The special behavior and execution order of autouse fixtures.
This file serves as both a user guide and a conceptual reference for understanding and effectively leveraging fixtures in pytest-based test suites.
Detailed Explanations
Built-in Fixtures
These fixtures are provided by pytest out-of-the-box and cover common test setup needs, such as capturing output, managing temporary directories, controlling logging, and accessing test configuration.
Fixture Name | Description |
|---|---|
Capture output to file descriptors 1 and 2 as text. | |
Capture output to file descriptors 1 and 2 as bytes. | |
`caplog` | Control and access logging output. |
`capsys` | Capture output to [sys.stdout](/projects/286/67223) and [sys.stderr](/projects/286/67223) as text. |
Capture output to [sys.stdout](/projects/286/67223) and [sys.stderr](/projects/286/67223) as bytes. | |
Like `capsys` but passes text through according to [--capture=](/projects/286/67356) option. | |
Store and retrieve values across pytest runs. | |
Inject a dict into the doctest namespace. | |
Temporarily modify classes, functions, dictionaries, environment variables (`os.environ`), etc. | |
Access pytest configuration and plugin hooks. | |
Add extra properties to a test record. | |
Add extra properties to a test suite record. | |
Record warnings emitted by tests. | |
`request` | Provides information about the executing test function. |
Provides a temporary test directory for testing pytest plugins. | |
`tmp_path` | Provides a [pathlib.Path](/projects/286/67376) object to a unique temporary directory per test function. |
Creates session-scoped temporary directories as [pathlib.Path](/projects/286/67376) objects. | |
Provides a [py.path.local](/projects/286/67409) temporary directory (deprecated in favor of `tmp_path`). | |
Creates session-scoped temporary directories as [py.path.local](/projects/286/67409) objects (deprecated). |
Usage example of a built-in fixture:
def test_write_and_read(tmp_path):
file = tmp_path / "example.txt"
file.write_text("hello pytest")
assert file.read_text() == "hello pytest"
Fixture Availability and Scope
Fixtures are available to tests based on the scope they are defined in:
Module-level fixtures: Available to all tests within that module, including those inside classes.
Class-level fixtures: Available only to tests inside that class.
Function-level fixtures: Available only to the test function itself (default).
Package and session scopes can also be defined for broader fixture lifetime.
Fixtures can request other fixtures regardless of scope, provided the requesting test has visibility of all involved fixtures. This is known as *dependency injection*.
Example illustrating fixture visibility from the test's perspective shows that tests can use fixtures defined in outer scopes transparently.
Sharing Fixtures with conftest.py
The special file `conftest.py` allows defining fixtures that are automatically discovered and shared across multiple test files within a directory (and its subdirectories unless overridden).
Key points:
Fixtures in a
conftest.pyfile are available to all tests in that directory tree.Nested
conftest.pyfiles can extend or override fixtures from parent directories.This mechanism supports modular test fixture sharing without explicit imports.
Example directory structure with `conftest.py` and tests illustrates fixture inheritance and overriding behavior.
Fixtures from Third-party Plugins
Fixtures can also be provided by third-party pytest plugins. These fixtures:
Are globally available if the plugin is installed.
Are searched after fixtures defined in the test suite itself.
Do not have a directory scope like
conftest.pyfixtures.Enable extensibility of pytest via reusable fixture sets.
An example shows how fixtures from plugins `plugin_a` and `plugin_b` integrate with user-defined fixtures during resolution.
Fixture Instantiation Order
Pytest determines the order of fixture setup based on three factors:
Scope: Fixtures with broader scope (e.g., session) are instantiated before narrower scope (e.g., function).
Dependencies: If fixture A depends on fixture B, B is set up first.
Autouse: Fixtures marked
autouse=Truerun before explicitly requested fixtures within their scope.
Higher-scoped fixtures execute first
Example:
A
sessionscoped fixture runs before afunctionscoped fixture requested by the test.
Dependency order
Fixture dependencies form a directed acyclic graph (DAG). Pytest topologically sorts fixtures so dependencies execute first.
If dependencies are ambiguous or incomplete, pytest may choose any valid order consistent with constraints.
Autouse fixtures execute first
Autouse fixtures apply transparently to tests.
If an autouse fixture depends on other fixtures, those dependencies become autouse for that particular test.
Autouse fixtures run before any explicitly requested fixture in the same scope.
Example graphs visualize how autouse fixtures reorder execution.
Important Notes
Fixture names, definition order, or request order do not control execution order beyond the three main factors.
Tests can use
pytest --fixturesto list all fixtures available in a test or module.Use
pytest --setup-planto see the order fixtures will be executed for a test.Autouse fixtures can have surprising effects by running even if a test does not explicitly request them.
Implementation Details
Pytest uses a fixture resolution algorithm based on scopes and declared dependencies to build an execution graph.
The graph is flattened to a linear execution order respecting autouse priority.
Fixtures defined in
conftest.pyare discovered recursively by traversing directory structure upward.Third-party plugin fixtures are registered via pytest’s plugin architecture and integrated last in the search order.
Interactions with Other Parts of the System
Test files/modules: Request fixtures via function parameters.
conftest.py: Provides fixtures at directory/package level scope, enabling fixture sharing.Third-party plugins: Extend fixture availability and functionality.
Pytest core: Manages fixture lifecycle (setup and teardown), discovery, and dependency resolution.
Test discovery and execution: Fixtures influence test environment setup and teardown phases.
Logging and output capturing: Built-in fixtures like
caplog,capsysinteract with pytest’s logging and output capture subsystems.
Visual Diagram: Fixture Resolution and Execution Structure
flowchart TD
A[Test Request]
B[Fixture Resolution Start]
C{Fixture Scope?}
D[Session Scoped Fixture]
E[Package Scoped Fixture]
F[Module Scoped Fixture]
G[Class Scoped Fixture]
H[Function Scoped Fixture]
I{Dependencies?}
J[Resolve Dependencies]
K[Autouse Fixtures?]
L[Execute Autouse Fixtures First]
M[Execute Requested Fixtures]
N[Test Runs]
A --> B
B --> C
C -->|Session| D
C -->|Package| E
C -->|Module| F
C -->|Class| G
C -->|Function| H
D --> I
E --> I
F --> I
G --> I
H --> I
I -->|Yes| J
I -->|No| K
J --> K
K -->|Yes| L
K -->|No| M
L --> M
M --> N
**Explanation:**
When a test runs, pytest starts fixture resolution.
It determines fixture scopes and orders execution by scope priority.
Dependencies between fixtures are resolved recursively.
Autouse fixtures are executed before requested fixtures within their scope.
After all fixtures are set up in the correct order, the test function executes.
Usage Examples Snippets
**Requesting fixtures in a test:**
def test_example(tmp_path, capsys):
file = tmp_path / "data.txt"
file.write_text("pytest fixtures")
out, err = capsys.readouterr()
assert file.read_text() == "pytest fixtures"
**Defining a fixture in `conftest.py`:**
import pytest
@pytest.fixture(scope="module")
def db_connection():
conn = create_db_connection()
yield conn
conn.close()
**Using autouse fixture:**
@pytest.fixture(autouse=True)
def enable_feature_flag():
# Setup code before each test
yield
# Teardown code after each test
Summary
The [fixtures.rst](/projects/286/67203) file is an essential, detailed guide to pytest fixtures, explaining their built-in forms, lifecycle, scope, availability rules, and execution order. It covers how fixtures can be shared across tests and directories, integrated from plugins, and controlled via autouse and dependencies.
Understanding this document enables pytest users to write robust, maintainable tests with complex setup/teardown needs, and to diagnose fixture-related behavior effectively.
**End of documentation for [fixtures.rst](/projects/286/67203).**