[Python-checkins] cpython (3.2): Issue #10979. unittest stdout buffering now works with class and module setup

michael.foord python-checkins at python.org
Thu Mar 17 18:43:25 CET 2011


http://hg.python.org/cpython/rev/0f7036ea0930
changeset: 68652:0f7036ea0930
branch: 3.2
parent: 68647:40f5355b6bf8
user: Michael Foord <michael at python.org>
date: Thu Mar 17 13:44:18 2011 -0400
summary:
 Issue #10979. unittest stdout buffering now works with class and module setup and teardown.
files:
 Lib/unittest/result.py
 Lib/unittest/suite.py
 Lib/unittest/test/test_result.py
 Misc/NEWS
diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py
--- a/Lib/unittest/result.py
+++ b/Lib/unittest/result.py
@@ -59,6 +59,9 @@
 "Called when the given test is about to be run"
 self.testsRun += 1
 self._mirrorOutput = False
+ self._setupStdout()
+
+ def _setupStdout(self):
 if self.buffer:
 if self._stderr_buffer is None:
 self._stderr_buffer = io.StringIO()
@@ -74,6 +77,10 @@
 
 def stopTest(self, test):
 """Called when the given test has been run"""
+ self._restoreStdout()
+ self._mirrorOutput = False
+
+ def _restoreStdout(self):
 if self.buffer:
 if self._mirrorOutput:
 output = sys.stdout.getvalue()
@@ -93,7 +100,6 @@
 self._stdout_buffer.truncate()
 self._stderr_buffer.seek(0)
 self._stderr_buffer.truncate()
- self._mirrorOutput = False
 
 def stopTestRun(self):
 """Called once after all tests are executed.
diff --git a/Lib/unittest/suite.py b/Lib/unittest/suite.py
--- a/Lib/unittest/suite.py
+++ b/Lib/unittest/suite.py
@@ -8,6 +8,11 @@
 __unittest = True
 
 
+def _call_if_exists(parent, attr):
+ func = getattr(parent, attr, lambda: None)
+ func()
+
+
 class BaseTestSuite(object):
 """A simple test suite that doesn't provide class or module shared fixtures.
 """
@@ -133,6 +138,7 @@
 
 setUpClass = getattr(currentClass, 'setUpClass', None)
 if setUpClass is not None:
+ _call_if_exists(result, '_setupStdout')
 try:
 setUpClass()
 except Exception as e:
@@ -142,6 +148,8 @@
 className = util.strclass(currentClass)
 errorName = 'setUpClass (%s)' % className
 self._addClassOrModuleLevelException(result, e, errorName)
+ finally:
+ _call_if_exists(result, '_restoreStdout')
 
 def _get_previous_module(self, result):
 previousModule = None
@@ -167,6 +175,7 @@
 return
 setUpModule = getattr(module, 'setUpModule', None)
 if setUpModule is not None:
+ _call_if_exists(result, '_setupStdout')
 try:
 setUpModule()
 except Exception as e:
@@ -175,6 +184,8 @@
 result._moduleSetUpFailed = True
 errorName = 'setUpModule (%s)' % currentModule
 self._addClassOrModuleLevelException(result, e, errorName)
+ finally:
+ _call_if_exists(result, '_restoreStdout')
 
 def _addClassOrModuleLevelException(self, result, exception, errorName):
 error = _ErrorHolder(errorName)
@@ -198,6 +209,7 @@
 
 tearDownModule = getattr(module, 'tearDownModule', None)
 if tearDownModule is not None:
+ _call_if_exists(result, '_setupStdout')
 try:
 tearDownModule()
 except Exception as e:
@@ -205,6 +217,8 @@
 raise
 errorName = 'tearDownModule (%s)' % previousModule
 self._addClassOrModuleLevelException(result, e, errorName)
+ finally:
+ _call_if_exists(result, '_restoreStdout')
 
 def _tearDownPreviousClass(self, test, result):
 previousClass = getattr(result, '_previousTestClass', None)
@@ -220,6 +234,7 @@
 
 tearDownClass = getattr(previousClass, 'tearDownClass', None)
 if tearDownClass is not None:
+ _call_if_exists(result, '_setupStdout')
 try:
 tearDownClass()
 except Exception as e:
@@ -228,7 +243,8 @@
 className = util.strclass(previousClass)
 errorName = 'tearDownClass (%s)' % className
 self._addClassOrModuleLevelException(result, e, errorName)
-
+ finally:
+ _call_if_exists(result, '_restoreStdout')
 
 
 class _ErrorHolder(object):
diff --git a/Lib/unittest/test/test_result.py b/Lib/unittest/test/test_result.py
--- a/Lib/unittest/test/test_result.py
+++ b/Lib/unittest/test/test_result.py
@@ -497,5 +497,72 @@
 self.assertEqual(result._original_stderr.getvalue(), expectedErrMessage)
 self.assertMultiLineEqual(message, expectedFullMessage)
 
+ def testBufferSetupClass(self):
+ result = unittest.TestResult()
+ result.buffer = True
+
+ class Foo(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ 1/0
+ def test_foo(self):
+ pass
+ suite = unittest.TestSuite([Foo('test_foo')])
+ suite(result)
+ self.assertEqual(len(result.errors), 1)
+
+ def testBufferTearDownClass(self):
+ result = unittest.TestResult()
+ result.buffer = True
+
+ class Foo(unittest.TestCase):
+ @classmethod
+ def tearDownClass(cls):
+ 1/0
+ def test_foo(self):
+ pass
+ suite = unittest.TestSuite([Foo('test_foo')])
+ suite(result)
+ self.assertEqual(len(result.errors), 1)
+
+ def testBufferSetUpModule(self):
+ result = unittest.TestResult()
+ result.buffer = True
+
+ class Foo(unittest.TestCase):
+ def test_foo(self):
+ pass
+ class Module(object):
+ @staticmethod
+ def setUpModule():
+ 1/0
+
+ Foo.__module__ = 'Module'
+ sys.modules['Module'] = Module
+ self.addCleanup(sys.modules.pop, 'Module')
+ suite = unittest.TestSuite([Foo('test_foo')])
+ suite(result)
+ self.assertEqual(len(result.errors), 1)
+
+ def testBufferTearDownModule(self):
+ result = unittest.TestResult()
+ result.buffer = True
+
+ class Foo(unittest.TestCase):
+ def test_foo(self):
+ pass
+ class Module(object):
+ @staticmethod
+ def tearDownModule():
+ 1/0
+
+ Foo.__module__ = 'Module'
+ sys.modules['Module'] = Module
+ self.addCleanup(sys.modules.pop, 'Module')
+ suite = unittest.TestSuite([Foo('test_foo')])
+ suite(result)
+ self.assertEqual(len(result.errors), 1)
+
+
 if __name__ == '__main__':
 unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@
 Core and Builtins
 -----------------
 
+- Issue #10979: unittest stdout buffering now works with class and module
+ setup and teardown.
+
 - Issue #11510: Fixed optimizer bug which turned "a,b={1,1}" into "a,b=(1,1)".
 
 - Issue #11432: A bug was introduced in subprocess.Popen on posix systems with
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /