test_collection.py
Overview
[test_collection.py](/projects/286/67495) is a comprehensive test suite for verifying the collection mechanisms and related behaviors of the `pytest` testing framework. The file primarily focuses on ensuring that pytest correctly discovers, collects, and manages test items (functions, classes, modules) from the filesystem, Python packages, and custom plugins. It tests core pytest collection features such as:
Differentiating between collectors and test items.
Handling file system edge cases (e.g., ignored directories, virtual environments, symlinks).
Customization points through hooks and plugins.
Correct ordering and identification of parametrized tests.
Proper handling of collection errors and interaction with pytest's command-line options.
Integration of conftest.py files and configuration options affecting test discovery.
Compatibility with different import modes (
importlib,prepend,append).Handling of namespace packages and Python annotations.
This file uses the `pytest` testing framework itself and the `pytester` plugin extensively to simulate test environments, create test files dynamically, run pytest commands, and assert expected behaviors.
Detailed Entity Descriptions
Function: ensure_file(file_path: Path) -> Path
**Purpose:** Ensure that a file exists at the specified path, creating parent directories if necessary.
**Parameters:**
file_path(Path): The file path to ensure existence of.
**Returns:**
Path: The same file path passed in, after ensuring its existence.
**Usage Example:**
file = ensure_file(Path("/tmp/some/dir/file.txt"))
# file now exists on the filesystem
Class: TestCollector
Test cases related to basic collection principles and pytest node hierarchy.
Methods:
test_collect_versus_item(self) -> None
Asserts thatpytest.Collectorandpytest.Itemare distinct classes with no subclass relationship.test_check_equality(self, pytester: Pytester) -> None
Verifies equality and hashing behavior of collected test functions vs their parent modules.test_getparent_and_accessors(self, pytester: Pytester) -> None
Tests parent retrieval and attribute accessors (e.g.,.module,.cls,.instance) for collected nodes.test_getcustomfile_roundtrip(self, pytester: Pytester) -> None
Checks custom file type collection usingpytest_collect_filehook.test_can_skip_class_with_test_attr(self, pytester: Pytester) -> None
Ensures classes with__test__=Falseattribute are skipped during collection.
Class: TestCollectFS
Tests related to filesystem-based collection, including ignoring certain directories, virtual environment detection, and honoring collection-related config.
Key Methods:
test_ignored_certain_directories(self, pytester: Pytester) -> None
Asserts that directories likebuild,dist,.bzr, etc., are ignored by default.test_ignored_virtualenvs(self, pytester: Pytester, env_path: PurePath) -> None
Checks that tests inside virtual environments are ignored unless explicitly allowed.test_custom_norecursedirs(self, pytester: Pytester) -> None
Tests honoring ofnorecursedirsconfiguration to skip directories.test_testpaths_ini(self, pytester: Pytester, monkeypatch: MonkeyPatch) -> None
Teststestpathsini option restricting collection to specified subdirectories.test_missing_permissions_on_unselected_directory_doesnt_crash(self, pytester: Pytester) -> None
Ensures pytest does not crash when encountering directories without permissions that are not selected for collection.
Class: TestCollectPluginHookRelay
Tests proper relay of the `pytest_collect_file` hook for plugin-defined collection.
test_pytest_collect_file(self, pytester: Pytester) -> None
Verifies that a plugin'spytest_collect_filehook is called and behaves as expected.
Class: TestPrunetraceback
Tests related to error reporting and traceback pruning during collection.
test_custom_repr_failure(self, pytester: Pytester) -> None
Tests custom failure representation for collection errors.test_collection_error_traceback_is_clean(self, pytester: Pytester) -> None
Verifies that collection errors produce tracebacks without internal pytest frames.
Class: TestCustomConftests
Test scenarios involving custom collection behaviors configured via `conftest.py`.
test_ignore_collect_path(self, pytester: Pytester) -> None
Tests thepytest_ignore_collecthook to skip certain paths.test_collectignore_exclude_on_option(self, pytester: Pytester) -> None
Tests conditional ignoring of paths based on command line options.test_pytest_fs_collect_hooks_are_seen(self, pytester: Pytester) -> None
Verifies custom collection hooks for file system objects are invoked.
Class: TestSession
Tests on `pytest.main.Session` collection protocol and item reporting.
test_collect_topdir(self, pytester: Pytester) -> None
Tests collection starting at the top directory.test_collect_protocol_single_function(self, pytester: Pytester) -> None
Tests collection of a single test function and reporting.test_collect_protocol_method(self, pytester: Pytester) -> None
Tests collection of test methods in classes.test_collect_custom_nodes_multi_id(self, pytester: Pytester) -> None
Tests custom collection nodes and multiple collected items.test_collect_parametrized_order(self, pytester: Pytester) -> None
Verifies order preservation for parametrized tests.
Class: TestNodeKeywords
Tests related to keyword handling on collected nodes (used for test selection with `-k`).
test_keyword_matching_is_case_insensitive_by_default(self, pytester: Pytester) -> None
Checks case-insensitive keyword matching.test_duplicates_handled_correctly(self, pytester: Pytester) -> None
Ensures no duplicate keywords are introduced.test_unpacked_marks_added_to_keywords(self, pytester: Pytester) -> None
Tests that unpacked pytest marks are correctly added to keywords.
Class: TestCollectDirectoryHook
Tests involving the `pytest_collect_directory` hook for custom directory collection.
test_custom_directory_example(self, pytester: Pytester) -> None
Verifies example usage ofpytest_collect_directory.test_directory_ignored_if_none(self, pytester: Pytester) -> None
Checks that returningNonefrom the hook results in directory being ignored.
Other Notable Functions and Tests
Tests that verify behavior on collection errors, including exit codes and error reporting.
Tests that ensure proper fixture scoping relative to sibling conftests.
Tests for collecting from special files like
__init__.py.Tests for handling of symlinks, broken symlinks, and recursive symlinks.
Tests for compatibility with various import modes and namespace packages.
Regression tests for known issues (e.g., yield in tests disallowed, decoration issues).
Tests for deferred evaluation of annotations (Python 3.14+).
Tests that verify correct behavior of collection when using
--pyargs.Tests that check system-level exceptions are respected during collection.
Important Implementation Details
The test suite uses the
pytesterfixture extensively to create isolated pytest test environments, create files and directories, run pytest commands, and capture outputs.Custom plugins and hooks are often defined inline in test source strings to simulate specific edge cases or features.
Symlink handling is tested with helper function
symlink_or_skipimported from_pytest.pathlib.Collection behavior is tested against many configuration options (
norecursedirs,testpaths,collect_ignore,import-mode, etc.) to ensure pytest respects user configuration.Error handling tests often verify that pytest aborts collection or continues based on flags like
--maxfailor--continue-on-collection-errors.The tests ensure that pytest's internal collection events (
pytest_collectstart,pytest_collectreport, etc.) are fired in the expected order and contain the proper data.Specialized classes and methods test the
from_parentfactory pattern used by pytest nodes to allow custom arguments during construction.
Interaction with Other System Components
This file tests the integration between pytest core collection machinery (
Session,Collector,Item) and user-facing configuration (pytest.ini), command-line options, and plugin hooks.It verifies interplay with the filesystem and Python import system, including details like virtualenv detection (
_in_venv), symlink resolution, and namespace package handling.The test suite ensures compatibility with pytest's fixture system, conftest.py loading, and marker-based test selection.
The tests also cover the interplay between pytest's internal reporting, traceback formatting, and test outcomes.
Usage Examples
The tests themselves serve as usage examples for pytest collection behaviors. For instance, to test that a class with `__test__ = False` is skipped:
def test_can_skip_class_with_test_attr(pytester: Pytester) -> None:
pytester.makepyfile(
"""
class TestFoo(object):
__test__ = False
def __init__(self):
pass
def test_foo():
assert True
"""
)
result = pytester.runpytest()
result.stdout.fnmatch_lines(["collected 0 items", "*no tests ran in*"])
Or to create a custom file collector via a plugin:
def test_pytest_collect_file(self, pytester: Pytester) -> None:
wascalled = []
class Plugin:
def pytest_collect_file(self, file_path: Path) -> None:
if not file_path.name.startswith("."):
wascalled.append(file_path)
pytester.makefile(".abc", "xyz")
pytest.main(pytester.path, plugins=[Plugin()])
assert len(wascalled) == 1
assert wascalled[0].suffix == ".abc"
Visual Diagram: Class Structure Overview
The key class defined in this file is `TestCollector`, which is a test class containing multiple test methods for collection behavior. There are also several other test classes grouping related tests. Below is a simplified Mermaid class diagram summarizing the main test classes and their key methods or responsibilities:
classDiagram
class TestCollector {
+test_collect_versus_item()
+test_check_equality(pytester)
+test_getparent_and_accessors(pytester)
+test_getcustomfile_roundtrip(pytester)
+test_can_skip_class_with_test_attr(pytester)
}
class TestCollectFS {
+test_ignored_certain_directories(pytester)
+test_ignored_virtualenvs(pytester, env_path)
+test_custom_norecursedirs(pytester)
+test_testpaths_ini(pytester, monkeypatch)
+test_missing_permissions_on_unselected_directory_doesnt_crash(pytester)
}
class TestPrunetraceback {
+test_custom_repr_failure(pytester)
+test_collection_error_traceback_is_clean(pytester)
}
class TestSession {
+test_collect_topdir(pytester)
+test_collect_protocol_single_function(pytester)
+test_collect_protocol_method(pytester)
+test_collect_custom_nodes_multi_id(pytester)
+test_collect_parametrized_order(pytester)
}
class TestNodeKeywords {
+test_no_under(pytester)
+test_keyword_matching_is_case_insensitive_by_default(pytester)
+test_duplicates_handled_correctly(pytester)
+test_unpacked_marks_added_to_keywords(pytester)
}
class TestCustomConftests {
+test_ignore_collect_path(pytester)
+test_collectignore_exclude_on_option(pytester)
+test_pytest_fs_collect_hooks_are_seen(pytester)
}
%% Relation: All test classes inherit from object (implied)
TestCollector <|-- object
TestCollectFS <|-- object
TestPrunetraceback <|-- object
TestSession <|-- object
TestNodeKeywords <|-- object
TestCustomConftests <|-- object
Summary
The [test_collection.py](/projects/286/67495) file is an extensive pytest test module that validates the correctness and robustness of pytest's test collection subsystem. It covers a broad spectrum of scenarios from basic node relationships to complex plugin and filesystem interactions, ensuring pytest's core functionality remains reliable and configurable under various conditions.