Fix for potentials errors in constructing unittest failure messages. Plus skipped test methods no longer run setUp and tearDown (Issue 8059)
This commit is contained in:
parent
fc8a1ed70e
commit
53e8eeadd6
|
@ -3118,6 +3118,43 @@ class Test_TestSkipping(TestCase):
|
|||
self.assertEqual(result.unexpectedSuccesses, [test])
|
||||
self.assertTrue(result.wasSuccessful())
|
||||
|
||||
def test_skip_doesnt_run_setup(self):
|
||||
class Foo(unittest.TestCase):
|
||||
wasSetUp = False
|
||||
wasTornDown = False
|
||||
def setUp(self):
|
||||
Foo.wasSetUp = True
|
||||
def tornDown(self):
|
||||
Foo.wasTornDown = True
|
||||
@unittest.skip('testing')
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
result = unittest.TestResult()
|
||||
test = Foo("test_1")
|
||||
suite = unittest.TestSuite([test])
|
||||
suite.run(result)
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
self.assertFalse(Foo.wasSetUp)
|
||||
self.assertFalse(Foo.wasTornDown)
|
||||
|
||||
def test_decorated_skip(self):
|
||||
def decorator(func):
|
||||
def inner(*a):
|
||||
return func(*a)
|
||||
return inner
|
||||
|
||||
class Foo(unittest.TestCase):
|
||||
@decorator
|
||||
@unittest.skip('testing')
|
||||
def test_1(self):
|
||||
pass
|
||||
|
||||
result = unittest.TestResult()
|
||||
test = Foo("test_1")
|
||||
suite = unittest.TestSuite([test])
|
||||
suite.run(result)
|
||||
self.assertEqual(result.skipped, [(test, "testing")])
|
||||
|
||||
|
||||
class Test_Assertions(TestCase):
|
||||
|
@ -3220,6 +3257,16 @@ class TestLongMessage(TestCase):
|
|||
self.assertEquals(self.testableTrue._formatMessage(None, "foo"), "foo")
|
||||
self.assertEquals(self.testableTrue._formatMessage("foo", "bar"), "bar : foo")
|
||||
|
||||
# This blows up if _formatMessage uses string concatenation
|
||||
self.testableTrue._formatMessage(object(), 'foo')
|
||||
|
||||
def test_formatMessage_unicode_error(self):
|
||||
with warnings.catch_warnings(record=True):
|
||||
# This causes a UnicodeWarning due to its craziness
|
||||
one = ''.join(chr(i) for i in range(255))
|
||||
# this used to cause a UnicodeDecodeError constructing msg
|
||||
self.testableTrue._formatMessage(one, u'\uFFFD')
|
||||
|
||||
def assertMessages(self, methodName, args, errors):
|
||||
def getMethod(i):
|
||||
useTestableFalse = i < 2
|
||||
|
|
|
@ -45,14 +45,15 @@ def skip(reason):
|
|||
Unconditionally skip a test.
|
||||
"""
|
||||
def decorator(test_item):
|
||||
if isinstance(test_item, type) and issubclass(test_item, TestCase):
|
||||
test_item.__unittest_skip__ = True
|
||||
test_item.__unittest_skip_why__ = reason
|
||||
return test_item
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(*args, **kwargs):
|
||||
raise SkipTest(reason)
|
||||
return skip_wrapper
|
||||
if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
|
||||
@functools.wraps(test_item)
|
||||
def skip_wrapper(*args, **kwargs):
|
||||
raise SkipTest(reason)
|
||||
test_item = skip_wrapper
|
||||
|
||||
test_item.__unittest_skip__ = True
|
||||
test_item.__unittest_skip_why__ = reason
|
||||
return test_item
|
||||
return decorator
|
||||
|
||||
def skipIf(condition, reason):
|
||||
|
@ -268,14 +269,18 @@ class TestCase(object):
|
|||
|
||||
self._resultForDoCleanups = result
|
||||
result.startTest(self)
|
||||
if getattr(self.__class__, "__unittest_skip__", False):
|
||||
# If the whole class was skipped.
|
||||
|
||||
testMethod = getattr(self, self._testMethodName)
|
||||
if (getattr(self.__class__, "__unittest_skip__", False) or
|
||||
getattr(testMethod, "__unittest_skip__", False)):
|
||||
# If the class or method was skipped.
|
||||
try:
|
||||
self._addSkip(result, self.__class__.__unittest_skip_why__)
|
||||
skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
|
||||
or getattr(testMethod, '__unittest_skip_why__', ''))
|
||||
self._addSkip(result, skip_why)
|
||||
finally:
|
||||
result.stopTest(self)
|
||||
return
|
||||
testMethod = getattr(self, self._testMethodName)
|
||||
try:
|
||||
success = False
|
||||
try:
|
||||
|
@ -386,7 +391,12 @@ class TestCase(object):
|
|||
return msg or standardMsg
|
||||
if msg is None:
|
||||
return standardMsg
|
||||
return standardMsg + ' : ' + msg
|
||||
try:
|
||||
# don't switch to '{}' formatting in Python 2.X
|
||||
# it changes the way unicode input is handled
|
||||
return '%s : %s' % (standardMsg, msg)
|
||||
except UnicodeDecodeError:
|
||||
return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
|
||||
|
||||
|
||||
def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
|
||||
|
|
Loading…
Reference in New Issue