test_nodes.py
Overview
`test_nodes.py` is a test suite file for the `_pytest.nodes` module within the pytest testing framework. This file primarily focuses on verifying the correct behavior and enforcement of usage patterns related to pytest's internal `Node` class and its subclasses (`Item`, `Collector`, etc.). The tests cover:
Ensuring deprecated or disallowed ways of constructing
Nodeobjects raise appropriate exceptions.Detecting problematic subclassing patterns (such as diamond inheritance involving both
ItemandCollector).Verifying that warning emissions are correctly handled and that only proper warning types are accepted.
Testing helper functions related to path handling within nodes.
Confirming that failure messages reflect correct paths when the current working directory changes during test execution.
The file uses `pytest` as the testing framework and interacts heavily with the internal pytest APIs and classes.
Detailed Explanation of Functions
test_node_from_parent_disallowed_arguments()
Purpose: Verifies that calling
Node.from_parent()with disallowed keyword arguments (sessionorconfig) raises aTypeError.Parameters: None
Returns: None
Usage:
test_node_from_parent_disallowed_arguments()Behavior:
Calls
nodes.Node.from_parentwithsession=Noneand expects aTypeError.Calls
nodes.Node.from_parentwithconfig=Noneand expects aTypeError.
Context: Ensures that the new recommended constructor (
from_parent) is used correctly without legacy arguments.
test_node_direct_construction_deprecated()
Purpose: Ensures that directly constructing a
Nodeinstance via its constructor raises anOutcomeExceptionwith a deprecation message.Parameters: None
Returns: None
Usage:
test_node_direct_construction_deprecated()Behavior:
Attempts to create a
Nodeinstance directly usingnodes.Node(None, session=None).Expects an
OutcomeExceptionwith a message directing the user to useNode.from_parent()instead.
Context: Enforces the new style of node instantiation to maintain internal consistency.
test_subclassing_both_item_and_collector_deprecated(request, tmp_path: Path)
Purpose: Tests that subclassing both
nodes.Itemandnodes.File(collector) triggers deprecation warnings about diamond inheritance and legacy constructors.Parameters:
request: pytest built-in fixture representing the current test request context.tmp_path: Path: pytest fixture providing a temporary directory as aPathobject.
Returns: None
Usage:
test_subclassing_both_item_and_collector_deprecated(request, tmp_path)Behavior:
Dynamically defines a class
SoWrongthat inherits from bothnodes.Itemandnodes.File.This class uses a legacy constructor signature.
Calls
SoWrong.from_parent()to trigger warnings.Captures warnings and asserts that they include messages about non-cooperative constructors and improper collector subclassing.
Context: Detects and warns against problematic multiple inheritance patterns that could break pytest internals.
test_node_warn_is_no_longer_only_pytest_warnings(pytester: Pytester, warn_type: type[Warning], msg: str)
Purpose: Parameterized test to verify that the
warn()method on aNodecan emit various types of warnings, not justPytestWarning.Parameters:
pytester: Pytester: pytest fixture providing test environment utilities.warn_type: type[Warning]: The warning class to test (DeprecationWarningorPytestWarning).msg: str: The message substring expected in the warning.
Returns: None
Usage:
test_node_warn_is_no_longer_only_pytest_warnings(pytester, DeprecationWarning, "deprecated")Behavior:
Creates test items using
pytester.getitems.Emits a warning of the specified type with the given message from the first item.
Asserts that the warning is captured appropriately.
Context: Ensures
Node.warn()accepts and emits general warnings correctly.
test_node_warning_enforces_warning_types(pytester: Pytester)
Purpose: Verifies that calling
warn()with a non-warning instance raises aValueError.Parameters:
pytester: Pytester
Returns: None
Usage:
test_node_warning_enforces_warning_types(pytester)Behavior:
Creates test items.
Calls
warn()on a test item with anExceptioninstance (not aWarning).Expects a
ValueErrorwith a message about requiring aWarninginstance.
Context: Enforces API usage correctness.
test__check_initialpaths_for_relpath()
Purpose: Tests the helper function
_check_initialpaths_for_relpathto ensure it correctly calculates relative paths or returns expected values.Parameters: None
Returns: None
Usage:
test__check_initialpaths_for_relpath()Behavior:
Defines a set of "initial paths" containing the current working directory.
Confirms that a path equal to the cwd returns an empty string.
Confirms that a subpath returns the relative path string.
Confirms that a path outside the initial paths returns
None.
Context: Validates internal logic for path resolution in node handling.
test_failure_with_changed_cwd(pytester: Pytester)
Purpose: Confirms that when the current working directory changes during tests, failure messages report absolute paths correctly.
Parameters:
pytester: Pytester
Returns: None
Usage:
test_failure_with_changed_cwd(pytester)Behavior:
Creates a test file that changes the working directory inside a fixture.
The test deliberately fails.
Runs pytest on this test file.
Checks output lines to confirm the failure path is absolute (not relative to changed cwd).
Context: Ensures usability of failure reports when CWD changes during test execution.
Important Implementation Details
Use of
from_parent()Constructor: The test suite enforces the transition from legacy constructors to the newNode.from_parent()factory method, which is the recommended way to instantiate nodes in pytest internals. This avoids confusing or inconsistent initialization.Warnings Handling: The tests verify that the
warn()method on nodes accepts all subclasses ofWarning, not justPytestWarning. It also ensures that improper warnings raise errors, improving robustness.Deprecation and Compatibility: The suite captures warnings related to legacy subclassing patterns, particularly diamond inheritance involving both
ItemandCollectorbase classes, which can cause issues in pytest's node hierarchy and test collection.Path Handling Logic: The helper
_check_initialpaths_for_relpathis tested to confirm it returns appropriate relative paths orNonebased on whether the target path is within the initial paths. This is important for correct path reporting in test results.Test Isolation and Fixtures: Use of
pytesterandtmp_pathfixtures facilitates isolated test environments, including temporary directories and test files, to simulate real-world scenarios like directory changes.
Interactions with Other Parts of the System
_pytest.nodes Module: This file tests the internal
Nodeclass and its subclasses (Item,Collector,File, etc.) defined within_pytest.nodes. It ensures that those classes' construction and usage conform to expected patterns._pytest.pytester Plugin: The
pytesterfixture used here is part of the_pytest.pytestermodule, which allows dynamic creation of test files and running pytest programmatically for integration-style tests._pytest.outcomes & _pytest.warning_types: These modules provide exception and warning classes (
OutcomeException,PytestWarning) used in the tests to assert correct error handling and warning emission.Path Management: The tests rely on
pathlib.Pathfor path manipulations and validating relative vs. absolute paths.pytest Test Runner: The file itself is run by pytest and uses pytest's own testing utilities (
pytest.raises,pytest.warns,pytest.mark.parametrize).
Visual Diagram of Class and Function Relationships
flowchart TD
A[test_node_from_parent_disallowed_arguments]
B[test_node_direct_construction_deprecated]
C[test_subclassing_both_item_and_collector_deprecated]
D[test_node_warn_is_no_longer_only_pytest_warnings]
E[test_node_warning_enforces_warning_types]
F[test__check_initialpaths_for_relpath]
G[test_failure_with_changed_cwd]
subgraph "Test Suite: test_nodes.py"
A
B
C
D
E
F
G
end
A -->|calls| nodes.Node.from_parent
B -->|calls| nodes.Node.__init__
C -->|defines subclass| SoWrong[nodes.Item, nodes.File]
C -->|calls| SoWrong.from_parent
D -->|calls| pytester.getitems
D -->|calls| Node.warn
E -->|calls| Node.warn
F -->|tests| nodes._check_initialpaths_for_relpath
G -->|creates test file| pytester.makepyfile
G -->|runs pytest| pytester.runpytest
subgraph "Dependencies"
nodes._pytest_nodes["_pytest.nodes"]
pytester._pytest_pytester["_pytest.pytester"]
outcomes._pytest_outcomes["_pytest.outcomes"]
warning_types._pytest_warning_types["_pytest.warning_types"]
end
A --> nodes._pytest_nodes
B --> nodes._pytest_nodes
C --> nodes._pytest_nodes
D --> pytester._pytest_pytester
E --> pytester._pytest_pytester
F --> nodes._pytest_nodes
G --> pytester._pytest_pytester
Summary
`test_nodes.py` is a focused pytest test module that ensures the robustness, correctness, and expected usage of pytest's core `Node` class and related internals. It enforces new construction patterns, validates warning handling, detects deprecated subclassing patterns, and confirms path correctness in failure reporting. This test suite plays a vital role in maintaining the integrity of pytest's node and collection APIs as the framework evolves.