Skip to content

Commit

Permalink
Merge pull request #5768 from robholt/fixture-class-instance
Browse files Browse the repository at this point in the history
Fix self reference in function scoped fixtures
  • Loading branch information
nicoddemus authored Aug 30, 2019
2 parents 667c646 + 955dc6d commit bd57307
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ Raphael Castaneda
Raphael Pierzina
Raquel Alegre
Ravi Chandra
Robert Holt
Roberto Polli
Roland Puntaier
Romain Dorgueil
Expand Down
2 changes: 2 additions & 0 deletions changelog/2270.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed ``self`` reference in function-scoped fixtures defined plugin classes: previously ``self``
would be a reference to a *test* class, not the *plugin* class.
6 changes: 6 additions & 0 deletions src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,12 @@ def resolve_fixture_function(fixturedef, request):
# request.instance so that code working with "fixturedef" behaves
# as expected.
if request.instance is not None:
# handle the case where fixture is defined not in a test class, but some other class
# (for example a plugin class with a fixture), see #2270
if hasattr(fixturefunc, "__self__") and not isinstance(
request.instance, fixturefunc.__self__.__class__
):
return fixturefunc
fixturefunc = getimfunc(fixturedef.func)
if fixturefunc != fixturedef.func:
fixturefunc = fixturefunc.__get__(request.instance)
Expand Down
32 changes: 32 additions & 0 deletions testing/python/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -3946,6 +3946,38 @@ def test_2(fix):
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2)

def test_class_fixture_self_instance(self, testdir):
"""Check that plugin classes which implement fixtures receive the plugin instance
as self (see #2270).
"""
testdir.makeconftest(
"""
import pytest
def pytest_configure(config):
config.pluginmanager.register(MyPlugin())
class MyPlugin():
def __init__(self):
self.arg = 1
@pytest.fixture(scope='function')
def myfix(self):
assert isinstance(self, MyPlugin)
return self.arg
"""
)

testdir.makepyfile(
"""
class TestClass(object):
def test_1(self, myfix):
assert myfix == 1
"""
)
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1)


def test_call_fixture_function_error():
"""Check if an error is raised if a fixture function is called directly (#4545)"""
Expand Down

0 comments on commit bd57307

Please sign in to comment.