test_setupplan.py
Overview
The `test_setupplan.py` file contains automated test cases designed to verify the correctness of pytest's **`--setup-plan`** output. This pytest command-line option displays the planned setup and teardown steps for fixtures used in tests without actually executing them, enabling users to understand fixture lifetimes and dependencies.
This file specifically tests:
That fixtures are listed but not executed when using
--setup-plan.Correct display of setup and teardown messages for fixtures with different scopes (function, class, module, session).
That the number of setup and teardown messages corresponds correctly to fixture lifetimes.
Consistency between the outputs of
--setup-planand --setup-show.
The tests use the `Pytester` utility from `_pytest.pytester`, which provides an isolated environment to dynamically create test files, execute pytest commands, and inspect their output.
Classes & Functions
test_show_fixtures_and_test(pytester: Pytester, dummy_yaml_custom_test: None) -> None
**Purpose:** Verify that fixtures are listed by `--setup-plan` without being executed.
**Parameters:**
pytester: Instance ofPytesterused to create and run pytest tests dynamically.dummy_yaml_custom_test: A placeholder fixture (not used in this function).
**Returns:**
None
**Description:** Creates a simple test file with a fixture `arg` that will fail if executed (via `assert False`) and a test that uses it. Runs pytest with `--setup-plan`, which should **not execute** the fixture (no assertion failure). Then asserts that the output includes the setup and teardown messages for the fixture `arg` and the test invocation referencing the fixture usage.
**Usage Example:** This function itself is a test case, so no direct usage beyond pytest running it.
test_show_multi_test_fixture_setup_and_teardown_correctly_simple(pytester: Pytester) -> None
**Purpose:** Verify that fixtures with a **class scope** display a single setup and teardown in `--setup-plan` output, even when used by multiple tests.
**Parameters:**
pytester: Instance ofPytester.
**Returns:**
None
**Description:** Creates a test class [TestClass](/projects/286/67298) with two tests sharing a class-scoped fixture `fix`. The test asserts that the `--setup-plan` output contains exactly one `SETUP` and one `TEARDOWN` message for the fixture, not one per test. This addresses a known bug (issue #2049) where the display incorrectly showed setup/teardown for each test despite the fixture's longer lifetime.
test_show_multi_test_fixture_setup_and_teardown_same_as_setup_show(pytester: Pytester) -> None
**Purpose:** Ensure that the `--setup-plan` output's setup and teardown messages match exactly those from [--setup-show](/projects/286/67223).
**Parameters:**
pytester: Instance ofPytester.
**Returns:**
None
**Description:** Creates fixtures with various scopes (`session`, `module`, `class`, `function`) and tests that use all of them. Runs pytest twice, once with `--setup-plan` and once with [--setup-show](/projects/286/67223). Then extracts all lines containing `SETUP` or `TEARDOWN` and asserts the two outputs are identical, ensuring consistency between these two flags.
Important Implementation Details
The tests do not execute fixtures when run with
--setup-plan; they validate the correctness and formatting of the planned setup/teardown output.The pytester.makepyfile() method dynamically writes Python test code as a string, allowing isolated test scenarios.
The pytester.runpytest() method runs pytest with specified command-line options and captures the output and return code.
Output lines are filtered using substring matching and fnmatch_lines for pattern matching to verify expected messages.
The tests check for correct fixture lifecycle representation, especially for longer-lived fixtures (e.g., class-scoped).
These tests focus on the display and planning aspects of pytest's fixture handling, not actual execution behavior.
Interaction with Other Parts of the System
This file tests the output of pytest's core fixture management system when run with the
--setup-planand --setup-show options.It depends on
Pytester, a pytest internal utility, to create ephemeral test environments and invoke pytest runs programmatically.The tests indirectly verify the internal fixture tracking and reporting logic within pytest's setup/teardown machinery.
These tests help ensure that the user-facing CLI output of pytest remains accurate and informative, aiding debugging and fixture lifecycle understanding.
It does not modify or depend heavily on other project-specific code but validates pytest's own runtime behavior.
Visual Diagram
classDiagram
test_show_fixtures_and_test --|> Function
test_show_multi_test_fixture_setup_and_teardown_correctly_simple --|> Function
test_show_multi_test_fixture_setup_and_teardown_same_as_setup_show --|> Function
class test_show_fixtures_and_test {
+pytester: Pytester
+dummy_yaml_custom_test: None
+-> None
}
class test_show_multi_test_fixture_setup_and_teardown_correctly_simple {
+pytester: Pytester
+-> None
}
class test_show_multi_test_fixture_setup_and_teardown_same_as_setup_show {
+pytester: Pytester
+-> None
}
Summary
`test_setupplan.py` is a set of pytest-based functional tests that validate the correctness and consistency of the `--setup-plan` output in pytest's fixture management system. The tests dynamically create example test cases with fixtures of various scopes and verify that the planned setup and teardown steps are displayed correctly and consistently with other pytest options. This helps maintain the reliability of pytest's fixture lifecycle reporting, an important feature for debugging and understanding test dependencies.
Appendix
Example output snippet tested in test_show_fixtures_and_test
SETUP F arg
test_arg (fixtures used: arg)
TEARDOWN F arg
This confirms that the fixture setup and teardown are planned but not executed.
If you need further details or examples on how to extend these tests for other fixture scopes or complex dependency graphs, feel free to ask!