Browse Source

Allowed skipIf/UnlessDBFeature to accept several feature strings

Claude Paroz 10 năm trước cách đây
mục cha
commit
5675eb371f
3 tập tin đã thay đổi với 85 bổ sung16 xóa
  1. 12 8
      django/test/testcases.py
  2. 14 6
      docs/topics/testing/tools.txt
  3. 59 2
      tests/test_utils/tests.py

+ 12 - 8
django/test/testcases.py

@@ -976,20 +976,24 @@ def _deferredSkip(condition, reason):
     return decorator
 
 
-def skipIfDBFeature(feature):
+def skipIfDBFeature(*features):
     """
-    Skip a test if a database has the named feature
+    Skip a test if a database has at least one of the named features.
     """
-    return _deferredSkip(lambda: getattr(connection.features, feature, False),
-                         "Database has feature %s" % feature)
+    return _deferredSkip(
+        lambda: any(getattr(connection.features, feature, False) for feature in features),
+        "Database has feature(s) %s" % ", ".join(features)
+    )
 
 
-def skipUnlessDBFeature(feature):
+def skipUnlessDBFeature(*features):
     """
-    Skip a test unless a database has the named feature
+    Skip a test unless a database has all the named features.
     """
-    return _deferredSkip(lambda: not getattr(connection.features, feature, False),
-                         "Database doesn't support feature %s" % feature)
+    return _deferredSkip(
+        lambda: not all(getattr(connection.features, feature, False) for feature in features),
+        "Database doesn't support feature(s): %s" % ", ".join(features)
+    )
 
 
 class QuietWSGIRequestHandler(WSGIRequestHandler):

+ 14 - 6
docs/topics/testing/tools.txt

@@ -1610,10 +1610,10 @@ features class. See ``django.db.backends.BaseDatabaseFeatures``
 class for a full list of database features that can be used as a basis
 for skipping tests.
 
-.. function:: skipIfDBFeature(feature_name_string)
+.. function:: skipIfDBFeature(*feature_name_strings)
 
-Skip the decorated test or ``TestCase`` if the named database feature is
-supported.
+Skip the decorated test or ``TestCase`` if all of the named database features
+are supported.
 
 For example, the following test will not be executed if the database
 supports transactions (e.g., it would *not* run under PostgreSQL, but
@@ -1628,10 +1628,14 @@ it would under MySQL with MyISAM tables)::
 
     ``skipIfDBFeature`` can now be used to decorate a ``TestCase`` class.
 
-.. function:: skipUnlessDBFeature(feature_name_string)
+.. versionchanged:: 1.8
 
-Skip the decorated test or ``TestCase`` if the named database feature is *not*
-supported.
+    ``skipIfDBFeature`` can accept multiple feature strings.
+
+.. function:: skipUnlessDBFeature(*feature_name_strings)
+
+Skip the decorated test or ``TestCase`` if any of the named database features
+are *not* supported.
 
 For example, the following test will only be executed if the database
 supports transactions (e.g., it would run under PostgreSQL, but *not*
@@ -1645,3 +1649,7 @@ under MySQL with MyISAM tables)::
 .. versionchanged:: 1.7
 
     ``skipUnlessDBFeature`` can now be used to decorate a ``TestCase`` class.
+
+.. versionchanged:: 1.8
+
+    ``skipUnlessDBFeature`` can accept multiple feature strings.

+ 59 - 2
tests/test_utils/tests.py

@@ -19,14 +19,71 @@ from .views import empty_response
 
 
 class SkippingTestCase(TestCase):
+    def _assert_skipping(self, func, expected_exc):
+        # We cannot simply use assertRaises because a SkipTest exception will go unnoticed
+        try:
+            func()
+        except expected_exc:
+            pass
+        except Exception as e:
+            self.fail("No %s exception should have been raised for %s." % (
+                e.__class__.__name__, func.__name__))
+
     def test_skip_unless_db_feature(self):
-        "A test that might be skipped is actually called."
+        """
+        Testing the django.test.skipUnlessDBFeature decorator.
+        """
         # Total hack, but it works, just want an attribute that's always true.
         @skipUnlessDBFeature("__class__")
         def test_func():
             raise ValueError
 
-        self.assertRaises(ValueError, test_func)
+        @skipUnlessDBFeature("notprovided")
+        def test_func2():
+            raise ValueError
+
+        @skipUnlessDBFeature("__class__", "__class__")
+        def test_func3():
+            raise ValueError
+
+        @skipUnlessDBFeature("__class__", "notprovided")
+        def test_func4():
+            raise ValueError
+
+        self._assert_skipping(test_func, ValueError)
+        self._assert_skipping(test_func2, unittest.SkipTest)
+        self._assert_skipping(test_func3, ValueError)
+        self._assert_skipping(test_func4, unittest.SkipTest)
+
+    def test_skip_if_db_feature(self):
+        """
+        Testing the django.test.skipIfDBFeature decorator.
+        """
+        @skipIfDBFeature("__class__")
+        def test_func():
+            raise ValueError
+
+        @skipIfDBFeature("notprovided")
+        def test_func2():
+            raise ValueError
+
+        @skipIfDBFeature("__class__", "__class__")
+        def test_func3():
+            raise ValueError
+
+        @skipIfDBFeature("__class__", "notprovided")
+        def test_func4():
+            raise ValueError
+
+        @skipIfDBFeature("notprovided", "notprovided")
+        def test_func5():
+            raise ValueError
+
+        self._assert_skipping(test_func, unittest.SkipTest)
+        self._assert_skipping(test_func2, ValueError)
+        self._assert_skipping(test_func3, unittest.SkipTest)
+        self._assert_skipping(test_func4, unittest.SkipTest)
+        self._assert_skipping(test_func5, ValueError)
 
 
 class SkippingClassTestCase(TestCase):