Allowed skipIf/UnlessDBFeature to accept several feature strings

This commit is contained in:
Claude Paroz 2014-08-23 18:01:33 +02:00
parent e02f45d5ea
commit 5675eb371f
3 changed files with 85 additions and 16 deletions

View File

@ -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):

View File

@ -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.

View File

@ -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):