[Python-checkins] bpo-41620: TestCase.run() now always return a TestResult instance (GH-28030)

ambv webhook-mailer at python.org
Mon Aug 30 09:16:33 EDT 2021


https://github.com/python/cpython/commit/7e246a3a7b43762480ee4fe0cfb859e8e997a8c8
commit: 7e246a3a7b43762480ee4fe0cfb859e8e997a8c8
branch: main
author: Serhiy Storchaka <storchaka at gmail.com>
committer: ambv <lukasz at langa.pl>
date: 2021-08-30T15:16:25+02:00
summary:

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 at gmail.com>

files:
A Misc/NEWS.d/next/Library/2021-08-29-14-49-22.bpo-41620.WJ6PFL.rst
M Lib/unittest/case.py
M Lib/unittest/test/test_skipping.py

diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
index 8775ba9e241c44..2d193eb144a23d 100644
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -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
diff --git a/Lib/unittest/test/test_skipping.py b/Lib/unittest/test/test_skipping.py
index 3adde41b04e737..79b27e6daae255 100644
--- a/Lib/unittest/test/test_skipping.py
+++ b/Lib/unittest/test/test_skipping.py
@@ -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__":
diff --git a/Misc/NEWS.d/next/Library/2021-08-29-14-49-22.bpo-41620.WJ6PFL.rst b/Misc/NEWS.d/next/Library/2021-08-29-14-49-22.bpo-41620.WJ6PFL.rst
new file mode 100644
index 00000000000000..7674d4c9532a27
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-08-29-14-49-22.bpo-41620.WJ6PFL.rst
@@ -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.



More information about the Python-checkins mailing list