fix issue203 - fixture functions with a scope=function should have a "self" that points to the actual instance with which the test functions run.

This commit is contained in:
holger krekel 2012-10-20 09:59:20 +02:00
parent 525b08bc5c
commit 9ed127b5da
6 changed files with 45 additions and 4 deletions

View File

@ -1,6 +1,10 @@
Changes between 2.3.0 and 2.3.dev
-----------------------------------
- fix issue202 - fix regression: using "self" from fixture functions now
works as expected (it's the same "self" instance that a test method
which uses the fixture sees)
- skip pexpect using tests (test_pdb.py mostly) on freebsd* systems
due to pexpect not supporting it properly (hanging)

View File

@ -1,2 +1,2 @@
#
__version__ = '2.3.1.dev1'
__version__ = '2.3.1.dev2'

View File

@ -12,6 +12,16 @@ cutdir = py.path.local(_pytest.__file__).dirpath()
callable = py.builtin.callable
def getimfunc(func):
try:
return func.__func__
except AttributeError:
try:
return func.im_func
except AttributeError:
return func
class FixtureFunctionMarker:
def __init__(self, scope, params, autouse=False):
self.scope = scope
@ -1621,7 +1631,19 @@ class FixtureDef:
if self.unittest:
result = self.func(request.instance, **kwargs)
else:
result = self.func(**kwargs)
fixturefunc = self.func
# the fixture function needs to be bound to the actual
# request.instance so that code working with "self" behaves
# as expected. XXX request.instance should maybe return None
# instead of raising AttributeError
try:
if request.instance is not None:
fixturefunc = getimfunc(self.func)
if fixturefunc != self.func:
fixturefunc = fixturefunc.__get__(request.instance)
except AttributeError:
pass
result = fixturefunc(**kwargs)
self.active = True
self.cached_result = result
return result

View File

@ -16,7 +16,7 @@ For basic examples, see
- :doc:`../getting-started` for basic introductory examples
- :ref:`assert` for basic assertion examples
- :ref:`fixtures` for basic fixture/setup examples
- :ref:`parametrize` for basic fixture/setup examples
- :ref:`parametrize` for basic test function parametrization
- :doc:`../unittest` for basic unittest integration
- :doc:`../nose` for basic nosetests integration

View File

@ -24,7 +24,7 @@ def main():
name='pytest',
description='py.test: simple powerful testing with Python',
long_description = long_description,
version='2.3.1.dev1',
version='2.3.1.dev2',
url='http://pytest.org',
license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

View File

@ -2037,6 +2037,21 @@ class TestFixtureUsages:
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2)
def test_request_instance_issue203(self, testdir):
testdir.makepyfile("""
import pytest
class TestClass:
@pytest.fixture
def setup1(self, request):
assert self == request.instance
self.arg1 = 1
def test_hello(self, setup1):
assert self.arg1 == 1
""")
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1)
class TestFixtureManager:
def pytest_funcarg__testdir(self, request):
testdir = request.getfuncargvalue("testdir")