Clean up unittest TestCase objects after tests are complete (#1649).
Fix #1649 Users of unittest style TestCases will create expensive objects in setUp. We should clean up TestCase instances that are lying around so that they don't fill up memory.
This commit is contained in:
parent
07af307e4a
commit
e46e653794
1
AUTHORS
1
AUTHORS
|
@ -36,6 +36,7 @@ Christopher Gilling
|
||||||
Daniel Grana
|
Daniel Grana
|
||||||
Daniel Hahler
|
Daniel Hahler
|
||||||
Daniel Nuri
|
Daniel Nuri
|
||||||
|
Daniel Wandschneider
|
||||||
Danielle Jenkins
|
Danielle Jenkins
|
||||||
Dave Hunt
|
Dave Hunt
|
||||||
David Díaz-Barquero
|
David Díaz-Barquero
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
* Properly handle exceptions in ``multiprocessing`` tasks (`#1984`_).
|
* Properly handle exceptions in ``multiprocessing`` tasks (`#1984`_).
|
||||||
Thanks `@adborden`_ for the report and `@nicoddemus`_ for the PR.
|
Thanks `@adborden`_ for the report and `@nicoddemus`_ for the PR.
|
||||||
|
|
||||||
*
|
* Clean up unittest TestCase objects after tests are complete (`#1649`_).
|
||||||
|
Thanks `@d_b_w`_ for the report and PR.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
.. _@okulynyak: https://github.com/okulynyak
|
.. _@okulynyak: https://github.com/okulynyak
|
||||||
.. _@matclab: https://github.com/matclab
|
.. _@matclab: https://github.com/matclab
|
||||||
.. _@gdyuldin: https://github.com/gdyuldin
|
.. _@gdyuldin: https://github.com/gdyuldin
|
||||||
|
.. _@d_b_w: https://github.com/d_b_w
|
||||||
|
|
||||||
.. _#442: https://github.com/pytest-dev/pytest/issues/442
|
.. _#442: https://github.com/pytest-dev/pytest/issues/442
|
||||||
.. _#1976: https://github.com/pytest-dev/pytest/issues/1976
|
.. _#1976: https://github.com/pytest-dev/pytest/issues/1976
|
||||||
|
@ -45,6 +47,7 @@
|
||||||
.. _#1998: https://github.com/pytest-dev/pytest/issues/1998
|
.. _#1998: https://github.com/pytest-dev/pytest/issues/1998
|
||||||
.. _#2004: https://github.com/pytest-dev/pytest/issues/2004
|
.. _#2004: https://github.com/pytest-dev/pytest/issues/2004
|
||||||
.. _#2005: https://github.com/pytest-dev/pytest/issues/2005
|
.. _#2005: https://github.com/pytest-dev/pytest/issues/2005
|
||||||
|
.. _#1649: https://github.com/pytest-dev/pytest/issues/1649
|
||||||
|
|
||||||
|
|
||||||
3.0.3
|
3.0.3
|
||||||
|
|
|
@ -94,6 +94,9 @@ class TestCaseFunction(pytest.Function):
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
if hasattr(self._testcase, 'teardown_method'):
|
if hasattr(self._testcase, 'teardown_method'):
|
||||||
self._testcase.teardown_method(self._obj)
|
self._testcase.teardown_method(self._obj)
|
||||||
|
# Allow garbage collection on TestCase instance attributes.
|
||||||
|
self._testcase = None
|
||||||
|
self._obj = None
|
||||||
|
|
||||||
def startTest(self, testcase):
|
def startTest(self, testcase):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||||
import pytest
|
import pytest
|
||||||
|
import gc
|
||||||
|
|
||||||
def test_simple_unittest(testdir):
|
def test_simple_unittest(testdir):
|
||||||
testpath = testdir.makepyfile("""
|
testpath = testdir.makepyfile("""
|
||||||
|
@ -134,6 +135,28 @@ def test_teardown(testdir):
|
||||||
assert passed == 2
|
assert passed == 2
|
||||||
assert passed + skipped + failed == 2
|
assert passed + skipped + failed == 2
|
||||||
|
|
||||||
|
def test_teardown_issue1649(testdir):
|
||||||
|
"""
|
||||||
|
Are TestCase objects cleaned up? Often unittest TestCase objects set
|
||||||
|
attributes that are large and expensive during setUp.
|
||||||
|
|
||||||
|
The TestCase will not be cleaned up if the test fails, because it
|
||||||
|
would then exist in the stackframe.
|
||||||
|
"""
|
||||||
|
testpath = testdir.makepyfile("""
|
||||||
|
import unittest
|
||||||
|
class TestCaseObjectsShouldBeCleanedUp(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.an_expensive_object = 1
|
||||||
|
def test_demo(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
""")
|
||||||
|
testdir.inline_run("-s", testpath)
|
||||||
|
gc.collect()
|
||||||
|
for obj in gc.get_objects():
|
||||||
|
assert type(obj).__name__ != 'TestCaseObjectsShouldBeCleanedUp'
|
||||||
|
|
||||||
@pytest.mark.skipif("sys.version_info < (2,7)")
|
@pytest.mark.skipif("sys.version_info < (2,7)")
|
||||||
def test_unittest_skip_issue148(testdir):
|
def test_unittest_skip_issue148(testdir):
|
||||||
testpath = testdir.makepyfile("""
|
testpath = testdir.makepyfile("""
|
||||||
|
|
Loading…
Reference in New Issue