mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +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__', '')
 | 
					                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
 | 
				
			||||||
                            or getattr(testMethod, '__unittest_skip_why__', ''))
 | 
					                            or getattr(testMethod, '__unittest_skip_why__', ''))
 | 
				
			||||||
                self._addSkip(result, self, skip_why)
 | 
					                self._addSkip(result, self, skip_why)
 | 
				
			||||||
                return
 | 
					                return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            expecting_failure = (
 | 
					            expecting_failure = (
 | 
				
			||||||
                getattr(self, "__unittest_expecting_failure__", False) or
 | 
					                getattr(self, "__unittest_expecting_failure__", False) or
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,14 +14,16 @@ def test_skip_me(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_skip_me")
 | 
					        test = Foo("test_skip_me")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
 | 
					        self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "skip")])
 | 
					        self.assertEqual(result.skipped, [(test, "skip")])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        test.run()
 | 
					        result = test.run()
 | 
				
			||||||
        self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
					        self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
				
			||||||
                                  'stopTest', 'stopTestRun'])
 | 
					                                  'stopTest', 'stopTestRun'])
 | 
				
			||||||
 | 
					        self.assertEqual(result.skipped, [(test, "skip")])
 | 
				
			||||||
 | 
					        self.assertEqual(result.testsRun, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Try letting setUp skip the test now.
 | 
					        # Try letting setUp skip the test now.
 | 
				
			||||||
        class Foo(unittest.TestCase):
 | 
					        class Foo(unittest.TestCase):
 | 
				
			||||||
| 
						 | 
					@ -33,15 +35,17 @@ def test_nothing(self): pass
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_nothing")
 | 
					        test = Foo("test_nothing")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
 | 
					        self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "testing")])
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
        self.assertEqual(result.testsRun, 1)
 | 
					        self.assertEqual(result.testsRun, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        test.run()
 | 
					        result = test.run()
 | 
				
			||||||
        self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
					        self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
				
			||||||
                                  'stopTest', 'stopTestRun'])
 | 
					                                  'stopTest', 'stopTestRun'])
 | 
				
			||||||
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
 | 
					        self.assertEqual(result.testsRun, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_skipping_subtests(self):
 | 
					    def test_skipping_subtests(self):
 | 
				
			||||||
        class Foo(unittest.TestCase):
 | 
					        class Foo(unittest.TestCase):
 | 
				
			||||||
| 
						 | 
					@ -56,7 +60,7 @@ def test_skip_me(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_skip_me")
 | 
					        test = Foo("test_skip_me")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events, ['startTest', 'addSkip', 'addSkip',
 | 
					        self.assertEqual(events, ['startTest', 'addSkip', 'addSkip',
 | 
				
			||||||
                                  'addSkip', 'stopTest'])
 | 
					                                  'addSkip', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(len(result.skipped), 3)
 | 
					        self.assertEqual(len(result.skipped), 3)
 | 
				
			||||||
| 
						 | 
					@ -71,10 +75,12 @@ def test_skip_me(self):
 | 
				
			||||||
        self.assertEqual(result.skipped[2], (test, "skip 3"))
 | 
					        self.assertEqual(result.skipped[2], (test, "skip 3"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        test.run()
 | 
					        result = test.run()
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTestRun', 'startTest', 'addSkip', 'addSkip',
 | 
					                         ['startTestRun', 'startTest', 'addSkip', 'addSkip',
 | 
				
			||||||
                          'addSkip', 'stopTest', 'stopTestRun'])
 | 
					                          'addSkip', 'stopTest', 'stopTestRun'])
 | 
				
			||||||
 | 
					        self.assertEqual([msg for subtest, msg in result.skipped],
 | 
				
			||||||
 | 
					                         ['skip 1', 'skip 2', 'skip 3'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_skipping_decorators(self):
 | 
					    def test_skipping_decorators(self):
 | 
				
			||||||
        op_table = ((unittest.skipUnless, False, True),
 | 
					        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])
 | 
					            suite = unittest.TestSuite([test_do_skip, test_dont_skip])
 | 
				
			||||||
            events = []
 | 
					            events = []
 | 
				
			||||||
            result = LoggingResult(events)
 | 
					            result = LoggingResult(events)
 | 
				
			||||||
            suite.run(result)
 | 
					            self.assertIs(suite.run(result), result)
 | 
				
			||||||
            self.assertEqual(len(result.skipped), 1)
 | 
					            self.assertEqual(len(result.skipped), 1)
 | 
				
			||||||
            expected = ['startTest', 'addSkip', 'stopTest',
 | 
					            expected = ['startTest', 'addSkip', 'stopTest',
 | 
				
			||||||
                        'startTest', 'addSuccess', 'stopTest']
 | 
					                        'startTest', 'addSuccess', 'stopTest']
 | 
				
			||||||
| 
						 | 
					@ -105,16 +111,16 @@ def test_dont_skip(self): pass
 | 
				
			||||||
            self.assertTrue(result.wasSuccessful())
 | 
					            self.assertTrue(result.wasSuccessful())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            events = []
 | 
					            events = []
 | 
				
			||||||
            test_do_skip.run()
 | 
					            result = test_do_skip.run()
 | 
				
			||||||
            self.assertEqual(len(result.skipped), 1)
 | 
					 | 
				
			||||||
            self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
					            self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
				
			||||||
                                      'stopTest', 'stopTestRun'])
 | 
					                                      'stopTest', 'stopTestRun'])
 | 
				
			||||||
 | 
					            self.assertEqual(result.skipped, [(test_do_skip, "testing")])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            events = []
 | 
					            events = []
 | 
				
			||||||
            test_dont_skip.run()
 | 
					            result = test_dont_skip.run()
 | 
				
			||||||
            self.assertEqual(len(result.skipped), 1)
 | 
					 | 
				
			||||||
            self.assertEqual(events, ['startTestRun', 'startTest', 'addSuccess',
 | 
					            self.assertEqual(events, ['startTestRun', 'startTest', 'addSuccess',
 | 
				
			||||||
                                      'stopTest', 'stopTestRun'])
 | 
					                                      'stopTest', 'stopTestRun'])
 | 
				
			||||||
 | 
					            self.assertEqual(result.skipped, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_skip_class(self):
 | 
					    def test_skip_class(self):
 | 
				
			||||||
        @unittest.skip("testing")
 | 
					        @unittest.skip("testing")
 | 
				
			||||||
| 
						 | 
					@ -128,15 +134,16 @@ def test_1(self):
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_1")
 | 
					        test = Foo("test_1")
 | 
				
			||||||
        suite = unittest.TestSuite([test])
 | 
					        suite = unittest.TestSuite([test])
 | 
				
			||||||
        suite.run(result)
 | 
					        self.assertIs(suite.run(result), result)
 | 
				
			||||||
        self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
 | 
					        self.assertEqual(events, ['startTest', 'addSkip', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "testing")])
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
        self.assertEqual(record, [])
 | 
					        self.assertEqual(record, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        test.run()
 | 
					        result = test.run()
 | 
				
			||||||
        self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
					        self.assertEqual(events, ['startTestRun', 'startTest', 'addSkip',
 | 
				
			||||||
                                  'stopTest', 'stopTestRun'])
 | 
					                                  'stopTest', 'stopTestRun'])
 | 
				
			||||||
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
        self.assertEqual(record, [])
 | 
					        self.assertEqual(record, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_skip_non_unittest_class(self):
 | 
					    def test_skip_non_unittest_class(self):
 | 
				
			||||||
| 
						 | 
					@ -150,7 +157,7 @@ class Foo(Mixin, unittest.TestCase):
 | 
				
			||||||
        result = unittest.TestResult()
 | 
					        result = unittest.TestResult()
 | 
				
			||||||
        test = Foo("test_1")
 | 
					        test = Foo("test_1")
 | 
				
			||||||
        suite = unittest.TestSuite([test])
 | 
					        suite = unittest.TestSuite([test])
 | 
				
			||||||
        suite.run(result)
 | 
					        self.assertIs(suite.run(result), result)
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "testing")])
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
        self.assertEqual(record, [])
 | 
					        self.assertEqual(record, [])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +169,7 @@ def test_die(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_die")
 | 
					        test = Foo("test_die")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTest', 'addExpectedFailure', 'stopTest'])
 | 
					                         ['startTest', 'addExpectedFailure', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(result.expectedFailures[0][0], test)
 | 
					        self.assertEqual(result.expectedFailures[0][0], test)
 | 
				
			||||||
| 
						 | 
					@ -177,7 +184,7 @@ def test_1(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_1")
 | 
					        test = Foo("test_1")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTest', 'addExpectedFailure', 'stopTest'])
 | 
					                         ['startTest', 'addExpectedFailure', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(result.expectedFailures[0][0], test)
 | 
					        self.assertEqual(result.expectedFailures[0][0], test)
 | 
				
			||||||
| 
						 | 
					@ -195,7 +202,7 @@ class Bar(Foo):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Bar("test_1")
 | 
					        test = Bar("test_1")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTest', 'addExpectedFailure', 'stopTest'])
 | 
					                         ['startTest', 'addExpectedFailure', 'stopTest'])
 | 
				
			||||||
        self.assertEqual(result.expectedFailures[0][0], test)
 | 
					        self.assertEqual(result.expectedFailures[0][0], test)
 | 
				
			||||||
| 
						 | 
					@ -218,7 +225,7 @@ def test_die(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_die")
 | 
					        test = Foo("test_die")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTest', 'addSubTestSuccess',
 | 
					                         ['startTest', 'addSubTestSuccess',
 | 
				
			||||||
                          'addExpectedFailure', 'stopTest'])
 | 
					                          'addExpectedFailure', 'stopTest'])
 | 
				
			||||||
| 
						 | 
					@ -234,7 +241,7 @@ def test_die(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_die")
 | 
					        test = Foo("test_die")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTest', 'addUnexpectedSuccess', 'stopTest'])
 | 
					                         ['startTest', 'addUnexpectedSuccess', 'stopTest'])
 | 
				
			||||||
        self.assertFalse(result.failures)
 | 
					        self.assertFalse(result.failures)
 | 
				
			||||||
| 
						 | 
					@ -256,7 +263,7 @@ def test_die(self):
 | 
				
			||||||
        events = []
 | 
					        events = []
 | 
				
			||||||
        result = LoggingResult(events)
 | 
					        result = LoggingResult(events)
 | 
				
			||||||
        test = Foo("test_die")
 | 
					        test = Foo("test_die")
 | 
				
			||||||
        test.run(result)
 | 
					        self.assertIs(test.run(result), result)
 | 
				
			||||||
        self.assertEqual(events,
 | 
					        self.assertEqual(events,
 | 
				
			||||||
                         ['startTest',
 | 
					                         ['startTest',
 | 
				
			||||||
                          'addSubTestSuccess', 'addSubTestSuccess',
 | 
					                          'addSubTestSuccess', 'addSubTestSuccess',
 | 
				
			||||||
| 
						 | 
					@ -280,7 +287,7 @@ def test_1(self):
 | 
				
			||||||
        result = unittest.TestResult()
 | 
					        result = unittest.TestResult()
 | 
				
			||||||
        test = Foo("test_1")
 | 
					        test = Foo("test_1")
 | 
				
			||||||
        suite = unittest.TestSuite([test])
 | 
					        suite = unittest.TestSuite([test])
 | 
				
			||||||
        suite.run(result)
 | 
					        self.assertIs(suite.run(result), result)
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "testing")])
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
        self.assertFalse(Foo.wasSetUp)
 | 
					        self.assertFalse(Foo.wasSetUp)
 | 
				
			||||||
        self.assertFalse(Foo.wasTornDown)
 | 
					        self.assertFalse(Foo.wasTornDown)
 | 
				
			||||||
| 
						 | 
					@ -300,7 +307,7 @@ def test_1(self):
 | 
				
			||||||
        result = unittest.TestResult()
 | 
					        result = unittest.TestResult()
 | 
				
			||||||
        test = Foo("test_1")
 | 
					        test = Foo("test_1")
 | 
				
			||||||
        suite = unittest.TestSuite([test])
 | 
					        suite = unittest.TestSuite([test])
 | 
				
			||||||
        suite.run(result)
 | 
					        self.assertIs(suite.run(result), result)
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "testing")])
 | 
					        self.assertEqual(result.skipped, [(test, "testing")])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_skip_without_reason(self):
 | 
					    def test_skip_without_reason(self):
 | 
				
			||||||
| 
						 | 
					@ -312,7 +319,7 @@ def test_1(self):
 | 
				
			||||||
        result = unittest.TestResult()
 | 
					        result = unittest.TestResult()
 | 
				
			||||||
        test = Foo("test_1")
 | 
					        test = Foo("test_1")
 | 
				
			||||||
        suite = unittest.TestSuite([test])
 | 
					        suite = unittest.TestSuite([test])
 | 
				
			||||||
        suite.run(result)
 | 
					        self.assertIs(suite.run(result), result)
 | 
				
			||||||
        self.assertEqual(result.skipped, [(test, "")])
 | 
					        self.assertEqual(result.skipped, [(test, "")])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					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