Skip to content

Commit

Permalink
Closes issue 10979. unittest buffering now works with class and modul…
Browse files Browse the repository at this point in the history
…e setup and teardown
  • Loading branch information
voidspace committed Mar 17, 2011
2 parents f694a40 + f40834f commit e9ff2ef
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
8 changes: 7 additions & 1 deletion Lib/unittest/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def startTest(self, test):
"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()
Expand All @@ -74,6 +77,10 @@ def startTestRun(self):

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()
Expand All @@ -93,7 +100,6 @@ def stopTest(self, test):
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.
Expand Down
18 changes: 17 additions & 1 deletion Lib/unittest/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand Down Expand Up @@ -133,6 +138,7 @@ def _handleClassSetUp(self, test, result):

setUpClass = getattr(currentClass, 'setUpClass', None)
if setUpClass is not None:
_call_if_exists(result, '_setupStdout')
try:
setUpClass()
except Exception as e:
Expand All @@ -142,6 +148,8 @@ def _handleClassSetUp(self, test, result):
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
Expand All @@ -167,6 +175,7 @@ def _handleModuleFixture(self, test, result):
return
setUpModule = getattr(module, 'setUpModule', None)
if setUpModule is not None:
_call_if_exists(result, '_setupStdout')
try:
setUpModule()
except Exception as e:
Expand All @@ -175,6 +184,8 @@ def _handleModuleFixture(self, test, result):
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)
Expand All @@ -198,13 +209,16 @@ def _handleModuleTearDown(self, result):

tearDownModule = getattr(module, 'tearDownModule', None)
if tearDownModule is not None:
_call_if_exists(result, '_setupStdout')
try:
tearDownModule()
except Exception as e:
if isinstance(result, _DebugResult):
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)
Expand All @@ -220,6 +234,7 @@ def _tearDownPreviousClass(self, test, result):

tearDownClass = getattr(previousClass, 'tearDownClass', None)
if tearDownClass is not None:
_call_if_exists(result, '_setupStdout')
try:
tearDownClass()
except Exception as e:
Expand All @@ -228,7 +243,8 @@ def _tearDownPreviousClass(self, test, result):
className = util.strclass(previousClass)
errorName = 'tearDownClass (%s)' % className
self._addClassOrModuleLevelException(result, e, errorName)

finally:
_call_if_exists(result, '_restoreStdout')


class _ErrorHolder(object):
Expand Down
67 changes: 67 additions & 0 deletions Lib/unittest/test/test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,5 +497,72 @@ def testBufferOutputAddErrorOrFailure(self):
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()
4 changes: 4 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ Core and Builtins
Library
-------


- Issue #10979: unittest stdout buffering now works with class and module
setup and teardown.

- Issue #11577: fix ResourceWarning triggered by improved binhex test coverage

- Issue #11243: fix the parameter querying methods of Message to work if
Expand Down

0 comments on commit e9ff2ef

Please sign in to comment.