mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	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
					
				
					 2 changed files with 70 additions and 13 deletions
				
			
		|  | @ -3118,6 +3118,43 @@ def test_die(self): | |||
|         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 @@ def test_formatMsg(self): | |||
|         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 | ||||
|         if not (isinstance(test_item, type) and issubclass(test_item, TestCase)): | ||||
|             @functools.wraps(test_item) | ||||
|             def skip_wrapper(*args, **kwargs): | ||||
|                 raise SkipTest(reason) | ||||
|         return skip_wrapper | ||||
|             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 @@ def run(self, result=None): | |||
| 
 | ||||
|         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 @@ def _formatMessage(self, msg, standardMsg): | |||
|             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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Michael Foord
						Michael Foord