@@ -1500,6 +1500,95 @@ def test_cleanup_called_the_right_number_of_times():
15001500 assert passed == 1
15011501
15021502
1503+ class TestClassCleanupErrors :
1504+ """
1505+ Make sure to show exceptions raised during class cleanup function (those registered
1506+ via addClassCleanup()).
1507+
1508+ See #11728.
1509+ """
1510+
1511+ def test_class_cleanups_failure_in_setup (self , pytester : Pytester ) -> None :
1512+ testpath = pytester .makepyfile (
1513+ """
1514+ import unittest
1515+ class MyTestCase(unittest.TestCase):
1516+ @classmethod
1517+ def setUpClass(cls):
1518+ def cleanup(n):
1519+ raise Exception(f"fail {n}")
1520+ cls.addClassCleanup(cleanup, 2)
1521+ cls.addClassCleanup(cleanup, 1)
1522+ raise Exception("fail 0")
1523+ def test(self):
1524+ pass
1525+ """
1526+ )
1527+ result = pytester .runpytest ("-s" , testpath )
1528+ result .assert_outcomes (passed = 0 , errors = 1 )
1529+ result .stdout .fnmatch_lines (
1530+ [
1531+ "*Unittest class cleanup errors *2 sub-exceptions*" ,
1532+ "*Exception: fail 1" ,
1533+ "*Exception: fail 2" ,
1534+ ]
1535+ )
1536+ result .stdout .fnmatch_lines (
1537+ [
1538+ "* ERROR at setup of MyTestCase.test *" ,
1539+ "E * Exception: fail 0" ,
1540+ ]
1541+ )
1542+
1543+ def test_class_cleanups_failure_in_teardown (self , pytester : Pytester ) -> None :
1544+ testpath = pytester .makepyfile (
1545+ """
1546+ import unittest
1547+ class MyTestCase(unittest.TestCase):
1548+ @classmethod
1549+ def setUpClass(cls):
1550+ def cleanup(n):
1551+ raise Exception(f"fail {n}")
1552+ cls.addClassCleanup(cleanup, 2)
1553+ cls.addClassCleanup(cleanup, 1)
1554+ def test(self):
1555+ pass
1556+ """
1557+ )
1558+ result = pytester .runpytest ("-s" , testpath )
1559+ result .assert_outcomes (passed = 1 , errors = 1 )
1560+ result .stdout .fnmatch_lines (
1561+ [
1562+ "*Unittest class cleanup errors *2 sub-exceptions*" ,
1563+ "*Exception: fail 1" ,
1564+ "*Exception: fail 2" ,
1565+ ]
1566+ )
1567+
1568+ def test_class_cleanup_1_failure_in_teardown (self , pytester : Pytester ) -> None :
1569+ testpath = pytester .makepyfile (
1570+ """
1571+ import unittest
1572+ class MyTestCase(unittest.TestCase):
1573+ @classmethod
1574+ def setUpClass(cls):
1575+ def cleanup(n):
1576+ raise Exception(f"fail {n}")
1577+ cls.addClassCleanup(cleanup, 1)
1578+ def test(self):
1579+ pass
1580+ """
1581+ )
1582+ result = pytester .runpytest ("-s" , testpath )
1583+ result .assert_outcomes (passed = 1 , errors = 1 )
1584+ result .stdout .fnmatch_lines (
1585+ [
1586+ "*ERROR at teardown of MyTestCase.test*" ,
1587+ "*Exception: fail 1" ,
1588+ ]
1589+ )
1590+
1591+
15031592def test_traceback_pruning (pytester : Pytester ) -> None :
15041593 """Regression test for #9610 - doesn't crash during traceback pruning."""
15051594 pytester .makepyfile (
0 commit comments