summaryrefslogtreecommitdiffstats
path: root/Lib/unittest
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/unittest')
-rw-r--r--Lib/unittest/suite.py15
-rw-r--r--Lib/unittest/test/test_setups.py6
-rw-r--r--Lib/unittest/test/test_suite.py42
3 files changed, 56 insertions, 7 deletions
diff --git a/Lib/unittest/suite.py b/Lib/unittest/suite.py
index cde5d38..176af57 100644
--- a/Lib/unittest/suite.py
+++ b/Lib/unittest/suite.py
@@ -57,12 +57,21 @@ class BaseTestSuite(object):
self.addTest(test)
def run(self, result):
- for test in self:
+ for index, test in enumerate(self):
if result.shouldStop:
break
test(result)
+ self._removeTestAtIndex(index)
return result
+ def _removeTestAtIndex(self, index):
+ """Stop holding a reference to the TestCase at index."""
+ try:
+ self._tests[index] = None
+ except TypeError:
+ # support for suite implementations that have overriden self._test
+ pass
+
def __call__(self, *args, **kwds):
return self.run(*args, **kwds)
@@ -87,7 +96,7 @@ class TestSuite(BaseTestSuite):
if getattr(result, '_testRunEntered', False) is False:
result._testRunEntered = topLevel = True
- for test in self:
+ for index, test in enumerate(self):
if result.shouldStop:
break
@@ -106,6 +115,8 @@ class TestSuite(BaseTestSuite):
else:
test.debug()
+ self._removeTestAtIndex(index)
+
if topLevel:
self._tearDownPreviousClass(None, result)
self._handleModuleTearDown(result)
diff --git a/Lib/unittest/test/test_setups.py b/Lib/unittest/test/test_setups.py
index b8d5aa4..bcd69a8 100644
--- a/Lib/unittest/test/test_setups.py
+++ b/Lib/unittest/test/test_setups.py
@@ -494,12 +494,10 @@ class TestSetups(unittest.TestCase):
Test.__module__ = 'Module'
sys.modules['Module'] = Module
- _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
- suite = unittest.TestSuite()
- suite.addTest(_suite)
-
messages = ('setUpModule', 'tearDownModule', 'setUpClass', 'tearDownClass', 'test_something')
for phase, msg in enumerate(messages):
+ _suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
+ suite = unittest.TestSuite([_suite])
with self.assertRaisesRegex(Exception, msg):
suite.debug()
diff --git a/Lib/unittest/test/test_suite.py b/Lib/unittest/test/test_suite.py
index 2db978d..1ad9b56 100644
--- a/Lib/unittest/test/test_suite.py
+++ b/Lib/unittest/test/test_suite.py
@@ -1,6 +1,8 @@
import unittest
+import gc
import sys
+import weakref
from .support import LoggingResult, TestEquality
@@ -300,7 +302,46 @@ class Test_TestSuite(unittest.TestCase, TestEquality):
# when the bug is fixed this line will not crash
suite.run(unittest.TestResult())
+ def test_remove_test_at_index(self):
+ suite = unittest.TestSuite()
+
+ suite._tests = [1, 2, 3]
+ suite._removeTestAtIndex(1)
+
+ self.assertEqual([1, None, 3], suite._tests)
+
+ def test_remove_test_at_index_not_indexable(self):
+ suite = unittest.TestSuite()
+ suite._tests = None
+
+ # if _removeAtIndex raises for noniterables this next line will break
+ suite._removeTestAtIndex(2)
+
+ def assert_garbage_collect_test_after_run(self, TestSuiteClass):
+
+ class Foo(unittest.TestCase):
+ def test_nothing(self):
+ pass
+
+ test = Foo('test_nothing')
+ wref = weakref.ref(test)
+
+ suite = TestSuiteClass([wref()])
+ suite.run(unittest.TestResult())
+
+ del test
+ # for the benefit of non-reference counting implementations
+ gc.collect()
+
+ self.assertEqual(suite._tests, [None])
+ self.assertIsNone(wref())
+
+ def test_garbage_collect_test_after_run_BaseTestSuite(self):
+ self.assert_garbage_collect_test_after_run(unittest.BaseTestSuite)
+
+ def test_garbage_collect_test_after_run_TestSuite(self):
+ self.assert_garbage_collect_test_after_run(unittest.TestSuite)
def test_basetestsuite(self):
class Test(unittest.TestCase):
@@ -363,6 +404,5 @@ class Test_TestSuite(unittest.TestCase, TestEquality):
self.assertFalse(result._testRunEntered)
-
if __name__ == '__main__':
unittest.main()