From cae1d0346923918e203c0d9ec605c852055d1c99 Mon Sep 17 00:00:00 2001 From: Casey Brooks Date: Thu, 25 Dec 2025 21:42:49 +0000 Subject: [PATCH] fix(xunit): hide autogenerated fixtures --- src/_pytest/python.py | 8 +- src/_pytest/unittest.py | 2 +- .../test_unittest_xunit_fixture_visibility.py | 106 ++++++++++++++++++ 3 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 testing/python/test_unittest_xunit_fixture_visibility.py diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 40116ab9c5a..c19d2ed4fb4 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -528,7 +528,7 @@ def _inject_setup_module_fixture(self) -> None: autouse=True, scope="module", # Use a unique name to speed up lookup. - name=f"xunit_setup_module_fixture_{self.obj.__name__}", + name=f"_xunit_setup_module_fixture_{self.obj.__name__}", ) def xunit_setup_module_fixture(request) -> Generator[None, None, None]: if setup_module is not None: @@ -557,7 +557,7 @@ def _inject_setup_function_fixture(self) -> None: autouse=True, scope="function", # Use a unique name to speed up lookup. - name=f"xunit_setup_function_fixture_{self.obj.__name__}", + name=f"_xunit_setup_function_fixture_{self.obj.__name__}", ) def xunit_setup_function_fixture(request) -> Generator[None, None, None]: if request.instance is not None: @@ -809,7 +809,7 @@ def _inject_setup_class_fixture(self) -> None: autouse=True, scope="class", # Use a unique name to speed up lookup. - name=f"xunit_setup_class_fixture_{self.obj.__qualname__}", + name=f"_xunit_setup_class_fixture_{self.obj.__qualname__}", ) def xunit_setup_class_fixture(cls) -> Generator[None, None, None]: if setup_class is not None: @@ -838,7 +838,7 @@ def _inject_setup_method_fixture(self) -> None: autouse=True, scope="function", # Use a unique name to speed up lookup. - name=f"xunit_setup_method_fixture_{self.obj.__qualname__}", + name=f"_xunit_setup_method_fixture_{self.obj.__qualname__}", ) def xunit_setup_method_fixture(self, request) -> Generator[None, None, None]: method = request.function diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index 719eb4e8823..3f88d7a9e2c 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -144,7 +144,7 @@ def cleanup(*args): scope=scope, autouse=True, # Use a unique name to speed up lookup. - name=f"unittest_{setup_name}_fixture_{obj.__qualname__}", + name=f"_unittest_{setup_name}_fixture_{obj.__qualname__}", ) def fixture(self, request: FixtureRequest) -> Generator[None, None, None]: if _is_skipped(self): diff --git a/testing/python/test_unittest_xunit_fixture_visibility.py b/testing/python/test_unittest_xunit_fixture_visibility.py new file mode 100644 index 00000000000..76212dd52bf --- /dev/null +++ b/testing/python/test_unittest_xunit_fixture_visibility.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import textwrap + + +def _run(pytester, *args): + return pytester.runpytest("--assert=plain", *args) + + +def test_unittest_autouse_fixture_hidden_by_default(pytester) -> None: + test_module = pytester.makepyfile( + textwrap.dedent( + """ + import unittest + + + class SampleTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + pass + + def test_dummy(self): + pass + """ + ) + ) + + default = _run(pytester, "--fixtures", str(test_module)) + default.stdout.no_fnmatch_line("*_unittest_setUpClass_fixture_*") + + verbose = _run(pytester, "-v", "--fixtures", str(test_module)) + verbose.stdout.fnmatch_lines_random( + ["*_unittest_setUpClass_fixture_* -- */_pytest/unittest.py:*"] + ) + + per_test = _run(pytester, "--fixtures-per-test", str(test_module)) + per_test.stdout.no_fnmatch_line("*_unittest_setUpClass_fixture_*") + + per_test_verbose = _run( + pytester, "-v", "--fixtures-per-test", str(test_module) + ) + per_test_verbose.stdout.fnmatch_lines_random( + ["*_unittest_setUpClass_fixture_* -- */_pytest/unittest.py:*"] + ) + + +def test_xunit_autouse_fixtures_hidden_by_default(pytester) -> None: + test_module = pytester.makepyfile( + textwrap.dedent( + """ + values = [] + + + def setup_module(module): + values.append("module") + + + def teardown_module(module): + values.append("teardown_module") + + + class TestSample: + @classmethod + def setup_class(cls): + values.append("class") + + @classmethod + def teardown_class(cls): + values.append("teardown_class") + + def setup_method(self, method): + values.append("method") + + def teardown_method(self, method): + values.append("teardown_method") + + def test_dummy(self): + pass + """ + ) + ) + + hidden_patterns = [ + "*_xunit_setup_module_fixture_*", + "*_xunit_setup_class_fixture_*", + "*_xunit_setup_method_fixture_*", + ] + visible_patterns = [ + "*_xunit_setup_module_fixture_* -- */_pytest/python.py:*", + "*_xunit_setup_class_fixture_* -- */_pytest/python.py:*", + "*_xunit_setup_method_fixture_* -- */_pytest/python.py:*", + ] + + default = _run(pytester, "--fixtures", str(test_module)) + for pattern in hidden_patterns: + default.stdout.no_fnmatch_line(pattern) + + verbose = _run(pytester, "-v", "--fixtures", str(test_module)) + verbose.stdout.fnmatch_lines_random(visible_patterns) + + per_test = _run(pytester, "--fixtures-per-test", str(test_module)) + for pattern in hidden_patterns: + per_test.stdout.no_fnmatch_line(pattern) + + per_test_verbose = _run(pytester, "-v", "--fixtures-per-test", str(test_module)) + per_test_verbose.stdout.fnmatch_lines_random(visible_patterns)