diff --git a/changelog/12907.improvement.rst b/changelog/12907.improvement.rst new file mode 100644 index 00000000000..b53ed1673b3 --- /dev/null +++ b/changelog/12907.improvement.rst @@ -0,0 +1 @@ +The missing fixture error for bare test functions which mistakenly declare a ``self`` parameter now suggests removing it. diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 05537ec01b2..0f9918d8002 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -1009,6 +1009,11 @@ def formatrepr(self) -> FixtureLookupErrorRepr: ) else: msg = f"fixture '{self.argname}' not found" + if self.argname == "self": + msg += ( + "\n hint: remove 'self' from the function definition if this " + "is not a method" + ) msg += "\n available fixtures: {}".format(", ".join(sorted(available))) msg += "\n use 'pytest --fixtures [testpath]' for help on them." diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index e4334af2145..dd6f2638b9f 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -687,6 +687,23 @@ def test_lookup_error(unknown): ) result.stdout.no_fnmatch_line("*INTERNAL*") + def test_funcarg_lookup_error_self_hint(self, pytester: Pytester) -> None: + pytester.makepyfile( + """ + def test_something(self): + pass + """ + ) + result = pytester.runpytest() + result.stdout.fnmatch_lines( + [ + "*ERROR at setup of test_something*", + "E fixture 'self' not found", + "> hint: remove 'self' from the function definition if this is not a method", + ] + ) + result.assert_outcomes(errors=1) + def test_fixture_excinfo_leak(self, pytester: Pytester) -> None: # on python2 sys.excinfo would leak into fixture executions pytester.makepyfile(