Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ Harshna
Henk-Jaap Wagenaar
Henry Schreiner
Holger Kohr
Huashuo Lei
Hugo van Kemenade
Hui Wang (coldnight)
Ian Bicking
Expand Down
1 change: 1 addition & 0 deletions changelog/15251.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reused a parent directory's collection results when multiple test files from that directory are supplied as explicit command-line arguments.
9 changes: 6 additions & 3 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -990,10 +990,13 @@ def collect(self) -> Iterator[nodes.Item | nodes.Collector]:
assert isinstance(matchparts[0], Path)
subnodes = matchnode._collect_path(matchparts[0], path_cache)
else:
# For backward compat, files given directly multiple
# times on the command line should not be deduplicated.
# A file argument reaches this collector as its final path
# part, but this is still the parent directory. Reuse the
# cached collection unless --keep-duplicates needs a fresh
# parent collection for an overlapping file argument.
handle_dupes = not (
len(matchparts) == 1
self.config.getoption("keepduplicates")
and len(matchparts) == 1
and isinstance(matchparts[0], Path)
and matchparts[0].is_file()
)
Expand Down
29 changes: 29 additions & 0 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,35 @@ def test_a(): pass
consecutive=True,
)

def test_explicit_file_arguments_collect_shared_directory_once(
self, pytester: Pytester
) -> None:
files = {f"tests/test_{i}.py": "def test_example(): pass" for i in range(8)}
pytester.makepyfile(**files)
pytester.makeconftest(
"""
from collections import Counter
from pathlib import Path

collected = Counter()

def pytest_collect_file(file_path, parent):
if file_path.name.startswith("test_"):
collected[file_path.name] += 1

def pytest_sessionfinish(session, exitstatus):
Path("collect-counts.txt").write_text(str(sum(collected.values())), encoding="utf-8")
"""
)

file_args = [f"tests/test_{i}.py" for i in range(4)]
result = pytester.runpytest_subprocess("--collect-only", *file_args)

assert result.ret == ExitCode.OK
assert int(
pytester.path.joinpath("collect-counts.txt").read_text(encoding="utf-8")
) == len(files)

def test_keep_duplicates_flag(self, pytester: Pytester) -> None:
"""Test that --keep-duplicates allows duplication."""
pytester.makepyfile(
Expand Down
Loading