]> granicus.if.org Git - python/commitdiff
#16935: unittest now counts the module as skipped if it raises SkipTest, instead...
authorEzio Melotti <ezio.melotti@gmail.com>
Fri, 1 Mar 2013 12:47:50 +0000 (14:47 +0200)
committerEzio Melotti <ezio.melotti@gmail.com>
Fri, 1 Mar 2013 12:47:50 +0000 (14:47 +0200)
Doc/library/unittest.rst
Lib/unittest/loader.py
Lib/unittest/test/test_discovery.py
Misc/NEWS

index 29ae1f933e3a56542aaaad5d09950b2cf7553bad..00eaa53f643ee2c0f7d1d2a2caa6dc55d133bf1b 100644 (file)
@@ -1493,7 +1493,9 @@ Loading and running tests
       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 @@ Loading and running tests
 
       .. 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:
index a5ac737fc26b4801a475075d2b9ac1c5a536da0d..2077fa3cdb6ab0cbc46c9d0f22bee1eed08fae65 100644 (file)
@@ -34,6 +34,14 @@ def _make_failed_test(classname, methodname, exception, suiteClass):
     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 @@ class TestLoader(object):
                 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:
index 1fdf9913c970436f089bcf6d83b335de5455970e..7569e3e12b08a2a935d1927b32058f3cdde1cd8d 100644 (file)
@@ -184,11 +184,9 @@ class TestDiscovery(unittest.TestCase):
         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 @@ class TestDiscovery(unittest.TestCase):
             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 @@ class TestDiscovery(unittest.TestCase):
         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()
 
index 57470e55fcef4031e3af4e6023dca31dcca65389..82030c98e77841881de42c5afecbf7aab8d70b33 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -270,6 +270,9 @@ Core and Builtins
 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