Commits

holger krekel  committed ed21f5c

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

  • Participants
  • Parent commits fa08012

Comments (0)

Files changed (6)

 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)
 

File _pytest/__init__.py

 #
-__version__ = '2.3.1.dev1'
+__version__ = '2.3.1.dev2'

File _pytest/python.py

 
 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
         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

File doc/en/example/index.txt

 - :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
 
         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'],

File testing/test_python.py

         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")