From cc3a25d1a6c16e6d533e579122b91a51dae33e62 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Sun, 14 Jun 2026 10:34:56 +0300 Subject: [PATCH] doc,testing: fix `scope="class"` instance methods This is deprecated, we should use classmethods for that. --- doc/en/how-to/fixtures.rst | 6 ++++-- testing/python/fixtures.py | 41 ++++++++++++++++++++++++++++---------- testing/python/metafunc.py | 3 ++- testing/test_unittest.py | 4 +++- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/doc/en/how-to/fixtures.rst b/doc/en/how-to/fixtures.rst index c89d38c4bab..48c278c194f 100644 --- a/doc/en/how-to/fixtures.rst +++ b/doc/en/how-to/fixtures.rst @@ -1049,7 +1049,8 @@ without having to repeat all those steps again. class TestLandingPageSuccess: @pytest.fixture(scope="class", autouse=True) - def login(self, driver, base_url, user): + @classmethod + def login(cls, driver, base_url, user): driver.get(urljoin(base_url, "/login")) page = LoginPage(driver) page.login(user) @@ -1092,7 +1093,8 @@ could handle it by adding something like this to the test file: class TestLandingPageBadCredentials: @pytest.fixture(scope="class") - def faux_user(self, user): + @classmethod + def faux_user(cls, user): _user = deepcopy(user) _user.password = "badpass" return _user diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index de3f7764aa7..024c13cd403 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -1185,10 +1185,13 @@ def test_setupdecorator_and_xunit(self, pytester: Pytester) -> None: pytester.makepyfile( """ import pytest + values = [] + @pytest.fixture(scope='module', autouse=True) def setup_module(): values.append("module") + @pytest.fixture(autouse=True) def setup_function(): values.append("function") @@ -1196,18 +1199,28 @@ def setup_function(): def test_func(): pass - class TestClass(object): + class TestClass: @pytest.fixture(scope="class", autouse=True) - def setup_class(self): + @classmethod + def setup_class(cls): values.append("class") + @pytest.fixture(autouse=True) def setup_method(self): values.append("method") + def test_method(self): pass + def test_all(): - assert values == ["module", "function", "class", - "function", "method", "function"] + assert values == [ + "module", + "function", + "class", + "function", + "method", + "function", + ] """ ) reprec = pytester.inline_run("-v") @@ -2467,7 +2480,8 @@ def pytest_generate_tests(metafunc): class TestClass: @pytest.fixture(scope="class", autouse=True) - def setup_teardown(self, item): + @classmethod + def setup_teardown(cls, item): values.append("setup-%d" % item) yield values.append("teardown-%d" % item) @@ -3246,21 +3260,26 @@ def param1(request): values = [] class TestClass(object): - @classmethod @pytest.fixture(scope="class", autouse=True) - def setup1(self, request, param1): + @classmethod + def setup1(cls, request, param1): values.append(1) - request.addfinalizer(self.teardown1) + request.addfinalizer(cls.teardown1) + @classmethod def teardown1(self): assert values.pop() == 1 + @pytest.fixture(scope="class", autouse=True) - def setup2(self, request, param1): + @classmethod + def setup2(cls, request, param1): values.append(2) - request.addfinalizer(self.teardown2) + request.addfinalizer(cls.teardown2) + @classmethod - def teardown2(self): + def teardown2(cls): assert values.pop() == 2 + def test(self): pass diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 96c4819e127..916bf1fdbd2 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -1743,7 +1743,8 @@ def test_2(): class Test: @pytest.fixture(scope="class") - def fixture(self, fixture): + @classmethod + def fixture(cls, fixture): pass @pytest.mark.parametrize("fixture", [0], indirect=True) diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 5d74d514c3c..20287d12cb3 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -867,9 +867,11 @@ def test_unittest_setup_interaction(pytester: Pytester, stmt: str) -> None: import pytest class MyTestCase(unittest.TestCase): @pytest.fixture(scope="class", autouse=True) - def perclass(self, request): + @classmethod + def perclass(cls, request): request.cls.hello = "world" {stmt} + @pytest.fixture(scope="function", autouse=True) def perfunction(self, request): request.instance.funcname = request.function.__name__