[Python-checkins] cpython: #16935: unittest now counts the module as skipped if it raises SkipTest,

ezio.melotti python-checkins at python.org
Fri Mar 1 13:48:09 CET 2013


http://hg.python.org/cpython/rev/61ce6deb4577
changeset:   82439:61ce6deb4577
user:        Ezio Melotti <ezio.melotti at gmail.com>
date:        Fri Mar 01 14:47:50 2013 +0200
summary:
  #16935: unittest now counts the module as skipped if it raises SkipTest, instead of counting it as an error.  Patch by Zachary Ware.

files:
  Doc/library/unittest.rst            |   8 ++++-
  Lib/unittest/loader.py              |  10 ++++++
  Lib/unittest/test/test_discovery.py |  27 ++++++++++++++--
  Misc/NEWS                           |   3 +
  4 files changed, 43 insertions(+), 5 deletions(-)


diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst
--- a/Doc/library/unittest.rst
+++ b/Doc/library/unittest.rst
@@ -1493,7 +1493,9 @@
       directory must be specified separately.
 
       If importing a module fails, for example due to a syntax error, then this
-      will be recorded as a single error and discovery will continue.
+      will be recorded as a single error and discovery will continue.  If the
+      import failure is due to ``SkipTest`` being raised, it will be recorded
+      as a skip instead of an error.
 
       If a test package name (directory with :file:`__init__.py`) matches the
       pattern then the package will be checked for a ``load_tests``
@@ -1512,6 +1514,10 @@
 
       .. versionadded:: 3.2
 
+      .. versionchanged:: 3.4
+         Modules that raise ``SkipTest`` on import are recorded as skips, not
+         errors.
+
 
    The following attributes of a :class:`TestLoader` can be configured either by
    subclassing or assignment on an instance:
diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py
--- a/Lib/unittest/loader.py
+++ b/Lib/unittest/loader.py
@@ -34,6 +34,14 @@
     TestClass = type(classname, (case.TestCase,), attrs)
     return suiteClass((TestClass(methodname),))
 
+def _make_skipped_test(methodname, exception, suiteClass):
+    @case.skip(str(exception))
+    def testSkipped(self):
+        pass
+    attrs = {methodname: testSkipped}
+    TestClass = type("ModuleSkipped", (case.TestCase,), attrs)
+    return suiteClass((TestClass(methodname),))
+
 def _jython_aware_splitext(path):
     if path.lower().endswith('$py.class'):
         return path[:-9]
@@ -259,6 +267,8 @@
                 name = self._get_name_from_path(full_path)
                 try:
                     module = self._get_module_from_name(name)
+                except case.SkipTest as e:
+                    yield _make_skipped_test(name, e, self.suiteClass)
                 except:
                     yield _make_failed_import_test(name, self.suiteClass)
                 else:
diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py
--- a/Lib/unittest/test/test_discovery.py
+++ b/Lib/unittest/test/test_discovery.py
@@ -184,11 +184,9 @@
         self.assertEqual(_find_tests_args, [(start_dir, 'pattern')])
         self.assertIn(top_level_dir, sys.path)
 
-    def test_discover_with_modules_that_fail_to_import(self):
-        loader = unittest.TestLoader()
-
+    def setup_import_issue_tests(self, fakefile):
         listdir = os.listdir
-        os.listdir = lambda _: ['test_this_does_not_exist.py']
+        os.listdir = lambda _: [fakefile]
         isfile = os.path.isfile
         os.path.isfile = lambda _: True
         orig_sys_path = sys.path[:]
@@ -198,6 +196,11 @@
             sys.path[:] = orig_sys_path
         self.addCleanup(restore)
 
+    def test_discover_with_modules_that_fail_to_import(self):
+        loader = unittest.TestLoader()
+
+        self.setup_import_issue_tests('test_this_does_not_exist.py')
+
         suite = loader.discover('.')
         self.assertIn(os.getcwd(), sys.path)
         self.assertEqual(suite.countTestCases(), 1)
@@ -206,6 +209,22 @@
         with self.assertRaises(ImportError):
             test.test_this_does_not_exist()
 
+    def test_discover_with_module_that_raises_SkipTest_on_import(self):
+        loader = unittest.TestLoader()
+
+        def _get_module_from_name(name):
+            raise unittest.SkipTest('skipperoo')
+        loader._get_module_from_name = _get_module_from_name
+
+        self.setup_import_issue_tests('test_skip_dummy.py')
+
+        suite = loader.discover('.')
+        self.assertEqual(suite.countTestCases(), 1)
+
+        result = unittest.TestResult()
+        suite.run(result)
+        self.assertEqual(len(result.skipped), 1)
+
     def test_command_line_handling_parseArgs(self):
         program = TestableTestProgram()
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -270,6 +270,9 @@
 Library
 -------
 
+- Issue #16935: unittest now counts the module as skipped if it raises SkipTest,
+  instead of counting it as an error.  Patch by Zachary Ware.
+
 - Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR.
 
 - Issue #17197: profile/cProfile modules refactored so that code of run() and

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list