diff --git a/changelog/3788.bugfix.rst b/changelog/3788.bugfix.rst new file mode 100644 index 000000000..aa391e28b --- /dev/null +++ b/changelog/3788.bugfix.rst @@ -0,0 +1 @@ +Fix ``AttributeError`` during teardown of ``TestCase`` subclasses which raise an exception during ``__init__``. diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index d6e7cb272..a135dbd53 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -69,6 +69,7 @@ class UnitTestCase(Class): class TestCaseFunction(Function): nofuncargs = True _excinfo = None + _testcase = None def setup(self): self._testcase = self.parent.obj(self.name) diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 482e89280..56fdebf48 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -989,3 +989,24 @@ def test_usefixtures_marker_on_unittest(base, testdir): result = testdir.runpytest("-s") result.assert_outcomes(passed=2) + + +def test_testcase_handles_init_exceptions(testdir): + """ + Regression test to make sure exceptions in the __init__ method are bubbled up correctly. + See https://github.com/pytest-dev/pytest/issues/3788 + """ + testdir.makepyfile( + """ + from unittest import TestCase + import pytest + class MyTestCase(TestCase): + def __init__(self, *args, **kwargs): + raise Exception("should raise this exception") + def test_hello(self): + pass + """ + ) + result = testdir.runpytest() + assert "should raise this exception" in result.stdout.str() + assert "ERROR at teardown of MyTestCase.test_hello" not in result.stdout.str()