mirror of
				https://github.com/python/cpython.git
				synced 2025-11-01 06:01:29 +00:00 
			
		
		
		
	bpo-41620: TestCase.run() now always return a TestResult instance (GH-28030)
Previously it returned None if the test class or method was decorated with a skipping decorator. Co-authored-by: Iman Tabrizian <iman.tabrizian@gmail.com>
This commit is contained in:
		
							parent
							
								
									d6cb5dd9e1
								
							
						
					
					
						commit
						7e246a3a7b
					
				
					 3 changed files with 34 additions and 24 deletions
				
			
		|  | @ -575,7 +575,7 @@ def run(self, result=None): | |||
|                 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') | ||||
|                             or getattr(testMethod, '__unittest_skip_why__', '')) | ||||
|                 self._addSkip(result, self, skip_why) | ||||
|                 return | ||||
|                 return result | ||||
| 
 | ||||
|             expecting_failure = ( | ||||
|                 getattr(self, "__unittest_expecting_failure__", False) or | ||||
|  |  | |||
|  | @ -14,14 +14,16 @@ def test_skip_me(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_skip_me") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) | ||||
|         self.assertEqual(result.skipped, [(test, "skip")]) | ||||
| 
 | ||||
|         events = [] | ||||
|         test.run() | ||||
|         result = test.run() | ||||
|         self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', | ||||
|                                   'stopTest', 'stopTestRun']) | ||||
|         self.assertEqual(result.skipped, [(test, "skip")]) | ||||
|         self.assertEqual(result.testsRun, 1) | ||||
| 
 | ||||
|         # Try letting setUp skip the test now. | ||||
|         class Foo(unittest.TestCase): | ||||
|  | @ -33,15 +35,17 @@ def test_nothing(self): pass | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_nothing") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
|         self.assertEqual(result.testsRun, 1) | ||||
| 
 | ||||
|         events = [] | ||||
|         test.run() | ||||
|         result = test.run() | ||||
|         self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', | ||||
|                                   'stopTest', 'stopTestRun']) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
|         self.assertEqual(result.testsRun, 1) | ||||
| 
 | ||||
|     def test_skipping_subtests(self): | ||||
|         class Foo(unittest.TestCase): | ||||
|  | @ -56,7 +60,7 @@ def test_skip_me(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_skip_me") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, ['startTest', 'addSkip', 'addSkip', | ||||
|                                   'addSkip', 'stopTest']) | ||||
|         self.assertEqual(len(result.skipped), 3) | ||||
|  | @ -71,10 +75,12 @@ def test_skip_me(self): | |||
|         self.assertEqual(result.skipped[2], (test, "skip 3")) | ||||
| 
 | ||||
|         events = [] | ||||
|         test.run() | ||||
|         result = test.run() | ||||
|         self.assertEqual(events, | ||||
|                          ['startTestRun', 'startTest', 'addSkip', 'addSkip', | ||||
|                           'addSkip', 'stopTest', 'stopTestRun']) | ||||
|         self.assertEqual([msg for subtest, msg in result.skipped], | ||||
|                          ['skip 1', 'skip 2', 'skip 3']) | ||||
| 
 | ||||
|     def test_skipping_decorators(self): | ||||
|         op_table = ((unittest.skipUnless, False, True), | ||||
|  | @ -95,7 +101,7 @@ def test_dont_skip(self): pass | |||
|             suite = unittest.TestSuite([test_do_skip, test_dont_skip]) | ||||
|             events = [] | ||||
|             result = LoggingResult(events) | ||||
|             suite.run(result) | ||||
|             self.assertIs(suite.run(result), result) | ||||
|             self.assertEqual(len(result.skipped), 1) | ||||
|             expected = ['startTest', 'addSkip', 'stopTest', | ||||
|                         'startTest', 'addSuccess', 'stopTest'] | ||||
|  | @ -105,16 +111,16 @@ def test_dont_skip(self): pass | |||
|             self.assertTrue(result.wasSuccessful()) | ||||
| 
 | ||||
|             events = [] | ||||
|             test_do_skip.run() | ||||
|             self.assertEqual(len(result.skipped), 1) | ||||
|             result = test_do_skip.run() | ||||
|             self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', | ||||
|                                       'stopTest', 'stopTestRun']) | ||||
|             self.assertEqual(result.skipped, [(test_do_skip, "testing")]) | ||||
| 
 | ||||
|             events = [] | ||||
|             test_dont_skip.run() | ||||
|             self.assertEqual(len(result.skipped), 1) | ||||
|             result = test_dont_skip.run() | ||||
|             self.assertEqual(events, ['startTestRun', 'startTest', 'addSuccess', | ||||
|                                       'stopTest', 'stopTestRun']) | ||||
|             self.assertEqual(result.skipped, []) | ||||
| 
 | ||||
|     def test_skip_class(self): | ||||
|         @unittest.skip("testing") | ||||
|  | @ -128,15 +134,16 @@ def test_1(self): | |||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_1") | ||||
|         suite = unittest.TestSuite([test]) | ||||
|         suite.run(result) | ||||
|         self.assertIs(suite.run(result), result) | ||||
|         self.assertEqual(events, ['startTest', 'addSkip', 'stopTest']) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
|         self.assertEqual(record, []) | ||||
| 
 | ||||
|         events = [] | ||||
|         test.run() | ||||
|         result = test.run() | ||||
|         self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip', | ||||
|                                   'stopTest', 'stopTestRun']) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
|         self.assertEqual(record, []) | ||||
| 
 | ||||
|     def test_skip_non_unittest_class(self): | ||||
|  | @ -150,7 +157,7 @@ class Foo(Mixin, unittest.TestCase): | |||
|         result = unittest.TestResult() | ||||
|         test = Foo("test_1") | ||||
|         suite = unittest.TestSuite([test]) | ||||
|         suite.run(result) | ||||
|         self.assertIs(suite.run(result), result) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
|         self.assertEqual(record, []) | ||||
| 
 | ||||
|  | @ -162,7 +169,7 @@ def test_die(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_die") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, | ||||
|                          ['startTest', 'addExpectedFailure', 'stopTest']) | ||||
|         self.assertEqual(result.expectedFailures[0][0], test) | ||||
|  | @ -177,7 +184,7 @@ def test_1(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_1") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, | ||||
|                          ['startTest', 'addExpectedFailure', 'stopTest']) | ||||
|         self.assertEqual(result.expectedFailures[0][0], test) | ||||
|  | @ -195,7 +202,7 @@ class Bar(Foo): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Bar("test_1") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, | ||||
|                          ['startTest', 'addExpectedFailure', 'stopTest']) | ||||
|         self.assertEqual(result.expectedFailures[0][0], test) | ||||
|  | @ -218,7 +225,7 @@ def test_die(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_die") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, | ||||
|                          ['startTest', 'addSubTestSuccess', | ||||
|                           'addExpectedFailure', 'stopTest']) | ||||
|  | @ -234,7 +241,7 @@ def test_die(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_die") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, | ||||
|                          ['startTest', 'addUnexpectedSuccess', 'stopTest']) | ||||
|         self.assertFalse(result.failures) | ||||
|  | @ -256,7 +263,7 @@ def test_die(self): | |||
|         events = [] | ||||
|         result = LoggingResult(events) | ||||
|         test = Foo("test_die") | ||||
|         test.run(result) | ||||
|         self.assertIs(test.run(result), result) | ||||
|         self.assertEqual(events, | ||||
|                          ['startTest', | ||||
|                           'addSubTestSuccess', 'addSubTestSuccess', | ||||
|  | @ -280,7 +287,7 @@ def test_1(self): | |||
|         result = unittest.TestResult() | ||||
|         test = Foo("test_1") | ||||
|         suite = unittest.TestSuite([test]) | ||||
|         suite.run(result) | ||||
|         self.assertIs(suite.run(result), result) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
|         self.assertFalse(Foo.wasSetUp) | ||||
|         self.assertFalse(Foo.wasTornDown) | ||||
|  | @ -300,7 +307,7 @@ def test_1(self): | |||
|         result = unittest.TestResult() | ||||
|         test = Foo("test_1") | ||||
|         suite = unittest.TestSuite([test]) | ||||
|         suite.run(result) | ||||
|         self.assertIs(suite.run(result), result) | ||||
|         self.assertEqual(result.skipped, [(test, "testing")]) | ||||
| 
 | ||||
|     def test_skip_without_reason(self): | ||||
|  | @ -312,7 +319,7 @@ def test_1(self): | |||
|         result = unittest.TestResult() | ||||
|         test = Foo("test_1") | ||||
|         suite = unittest.TestSuite([test]) | ||||
|         suite.run(result) | ||||
|         self.assertIs(suite.run(result), result) | ||||
|         self.assertEqual(result.skipped, [(test, "")]) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|  |  | |||
|  | @ -0,0 +1,3 @@ | |||
| :meth:`~unittest.TestCase.run` now always return a | ||||
| :class:`~unittest.TestResult` instance. Previously it returned ``None`` if | ||||
| the test class or method was decorated with a skipping decorator. | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Serhiy Storchaka
						Serhiy Storchaka