summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMichael Foord <fuzzyman@voidspace.org.uk>2010-03-07 20:22:12 (GMT)
committerMichael Foord <fuzzyman@voidspace.org.uk>2010-03-07 20:22:12 (GMT)
commit53e8eeadd60ab7566d2bc29a51ce286a890dd14b (patch)
tree7dbc8ce24d555d524f41f6d582015e279b53d687 /Lib
parentfc8a1ed70e2586871e06cea60dfd25a96ed5a313 (diff)
downloadcpython-53e8eeadd60ab7566d2bc29a51ce286a890dd14b.zip
cpython-53e8eeadd60ab7566d2bc29a51ce286a890dd14b.tar.gz
cpython-53e8eeadd60ab7566d2bc29a51ce286a890dd14b.tar.bz2
Fix for potentials errors in constructing unittest failure messages. Plus skipped test methods no longer run setUp and tearDown (Issue 8059)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_unittest.py47
-rw-r--r--Lib/unittest/case.py36
2 files changed, 70 insertions, 13 deletions
diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py
index 048f67b..be4811c 100644
--- a/Lib/test/test_unittest.py
+++ b/Lib/test/test_unittest.py
@@ -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
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
index aacd67c..19b196c 100644
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -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):