diff --git a/changelog/5390.bugfix.rst b/changelog/5390.bugfix.rst new file mode 100644 index 00000000000..1b8203b87a5 --- /dev/null +++ b/changelog/5390.bugfix.rst @@ -0,0 +1 @@ +Fix regression where the ``obj`` attribute of ``TestCase`` items was no longer bound methods. diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index da45e312f3a..216266979b7 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -108,11 +108,13 @@ class TestCaseFunction(Function): def setup(self): self._testcase = self.parent.obj(self.name) + self._obj = getattr(self._testcase, self.name) if hasattr(self, "_request"): self._request._fillfixtures() def teardown(self): self._testcase = None + self._obj = None def startTest(self, testcase): pass diff --git a/testing/test_unittest.py b/testing/test_unittest.py index a8555b35357..34c9dc821f3 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -139,6 +139,29 @@ def test_func2(self): reprec.assertoutcome(passed=2) +def test_function_item_obj_is_instance(testdir): + """item.obj should be a bound method on unittest.TestCase function items (#5390).""" + testdir.makeconftest( + """ + def pytest_runtest_makereport(item, call): + if call.when == 'call': + class_ = item.parent.obj + assert isinstance(item.obj.__self__, class_) + """ + ) + testdir.makepyfile( + """ + import unittest + + class Test(unittest.TestCase): + def test_foo(self): + pass + """ + ) + result = testdir.runpytest_inprocess() + result.stdout.fnmatch_lines(["*1 passed*"]) + + def test_teardown(testdir): testpath = testdir.makepyfile( """