mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
Issue #11798: TestSuite now drops references to own tests after execution.
This commit is contained in:
parent
6a53af893a
commit
eb97368451
6 changed files with 72 additions and 10 deletions
|
|
@ -1470,15 +1470,24 @@ Grouping tests
|
|||
|
||||
Tests grouped by a :class:`TestSuite` are always accessed by iteration.
|
||||
Subclasses can lazily provide tests by overriding :meth:`__iter__`. Note
|
||||
that this method maybe called several times on a single suite
|
||||
(for example when counting tests or comparing for equality)
|
||||
so the tests returned must be the same for repeated iterations.
|
||||
that this method may be called several times on a single suite (for
|
||||
example when counting tests or comparing for equality) so the tests
|
||||
returned by repeated iterations before :meth:`TestSuite.run` must be the
|
||||
same for each call iteration. After :meth:`TestSuite.run`, callers should
|
||||
not rely on the tests returned by this method unless the caller uses a
|
||||
subclass that overrides :meth:`TestSuite._removeTestAtIndex` to preserve
|
||||
test references.
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
In earlier versions the :class:`TestSuite` accessed tests directly rather
|
||||
than through iteration, so overriding :meth:`__iter__` wasn't sufficient
|
||||
for providing tests.
|
||||
|
||||
.. versionchanged:: 3.4
|
||||
In earlier versions the :class:`TestSuite` held references to each
|
||||
:class:`TestCase` after :meth:`TestSuite.run`. Subclasses can restore
|
||||
that behavior by overriding :meth:`TestSuite._removeTestAtIndex`.
|
||||
|
||||
In the typical usage of a :class:`TestSuite` object, the :meth:`run` method
|
||||
is invoked by a :class:`TestRunner` rather than by the end-user test harness.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -814,6 +814,7 @@ Daniel May
|
|||
Madison May
|
||||
Lucas Maystre
|
||||
Arnaud Mazin
|
||||
Matt McClure
|
||||
Rebecca McCreary
|
||||
Kirk McDonald
|
||||
Chris McDonough
|
||||
|
|
@ -1336,6 +1337,7 @@ Kevin Walzer
|
|||
Rodrigo Steinmuller Wanderley
|
||||
Ke Wang
|
||||
Greg Ward
|
||||
Tom Wardill
|
||||
Zachary Ware
|
||||
Jonas Wagner
|
||||
Barry Warsaw
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #11798: TestSuite now drops references to own tests after execution.
|
||||
|
||||
- Issue #16611: http.cookie now correctly parses the 'secure' and 'httponly'
|
||||
cookie flags.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue