Fixed #18551 -- Enabled skipIfDBFeature/skipUnlessDBFeature to decorate a class
Thanks Tim Graham for the review and improved patch.
This commit is contained in:
parent
a269ea4fe0
commit
6d52844b9b
|
@ -879,10 +879,19 @@ class TestCase(TransactionTestCase):
|
||||||
self.atomics[db_name].__exit__(None, None, None)
|
self.atomics[db_name].__exit__(None, None, None)
|
||||||
|
|
||||||
|
|
||||||
|
class CheckCondition(object):
|
||||||
|
"""Descriptor class for deferred condition checking"""
|
||||||
|
def __init__(self, cond_func):
|
||||||
|
self.cond_func = cond_func
|
||||||
|
|
||||||
|
def __get__(self, obj, objtype):
|
||||||
|
return self.cond_func()
|
||||||
|
|
||||||
|
|
||||||
def _deferredSkip(condition, reason):
|
def _deferredSkip(condition, reason):
|
||||||
def decorator(test_func):
|
def decorator(test_func):
|
||||||
if not (isinstance(test_func, type) and
|
if not (isinstance(test_func, type) and
|
||||||
issubclass(test_func, TestCase)):
|
issubclass(test_func, unittest.TestCase)):
|
||||||
@wraps(test_func)
|
@wraps(test_func)
|
||||||
def skip_wrapper(*args, **kwargs):
|
def skip_wrapper(*args, **kwargs):
|
||||||
if condition():
|
if condition():
|
||||||
|
@ -890,7 +899,9 @@ def _deferredSkip(condition, reason):
|
||||||
return test_func(*args, **kwargs)
|
return test_func(*args, **kwargs)
|
||||||
test_item = skip_wrapper
|
test_item = skip_wrapper
|
||||||
else:
|
else:
|
||||||
|
# Assume a class is decorated
|
||||||
test_item = test_func
|
test_item = test_func
|
||||||
|
test_item.__unittest_skip__ = CheckCondition(condition)
|
||||||
test_item.__unittest_skip_why__ = reason
|
test_item.__unittest_skip_why__ = reason
|
||||||
return test_item
|
return test_item
|
||||||
return decorator
|
return decorator
|
||||||
|
|
|
@ -1804,7 +1804,8 @@ for skipping tests.
|
||||||
|
|
||||||
.. function:: skipIfDBFeature(feature_name_string)
|
.. function:: skipIfDBFeature(feature_name_string)
|
||||||
|
|
||||||
Skip the decorated test if the named database feature is supported.
|
Skip the decorated test or ``TestCase`` if the named database feature is
|
||||||
|
supported.
|
||||||
|
|
||||||
For example, the following test will not be executed if the database
|
For example, the following test will not be executed if the database
|
||||||
supports transactions (e.g., it would *not* run under PostgreSQL, but
|
supports transactions (e.g., it would *not* run under PostgreSQL, but
|
||||||
|
@ -1815,9 +1816,13 @@ it would under MySQL with MyISAM tables)::
|
||||||
def test_transaction_behavior(self):
|
def test_transaction_behavior(self):
|
||||||
# ... conditional test code
|
# ... conditional test code
|
||||||
|
|
||||||
|
.. versionchanged:: 1.7
|
||||||
|
|
||||||
|
``skipIfDBFeature`` can now be used to decorate a ``TestCase`` class.
|
||||||
|
|
||||||
.. function:: skipUnlessDBFeature(feature_name_string)
|
.. function:: skipUnlessDBFeature(feature_name_string)
|
||||||
|
|
||||||
Skip the decorated test if the named database feature is *not*
|
Skip the decorated test or ``TestCase`` if the named database feature is *not*
|
||||||
supported.
|
supported.
|
||||||
|
|
||||||
For example, the following test will only be executed if the database
|
For example, the following test will only be executed if the database
|
||||||
|
@ -1828,3 +1833,7 @@ under MySQL with MyISAM tables)::
|
||||||
@skipUnlessDBFeature('supports_transactions')
|
@skipUnlessDBFeature('supports_transactions')
|
||||||
def test_transaction_behavior(self):
|
def test_transaction_behavior(self):
|
||||||
# ... conditional test code
|
# ... conditional test code
|
||||||
|
|
||||||
|
.. versionchanged:: 1.7
|
||||||
|
|
||||||
|
``skipUnlessDBFeature`` can now be used to decorate a ``TestCase`` class.
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import skip
|
|
||||||
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.forms import EmailField, IntegerField
|
from django.forms import EmailField, IntegerField
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
|
from django.test import SimpleTestCase, TestCase, skipIfDBFeature, skipUnlessDBFeature
|
||||||
from django.test.html import HTMLParseError, parse_html
|
from django.test.html import HTMLParseError, parse_html
|
||||||
from django.test.utils import CaptureQueriesContext, IgnoreAllDeprecationWarningsMixin
|
from django.test.utils import CaptureQueriesContext, IgnoreAllDeprecationWarningsMixin
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
@ -27,6 +26,29 @@ class SkippingTestCase(TestCase):
|
||||||
self.assertRaises(ValueError, test_func)
|
self.assertRaises(ValueError, test_func)
|
||||||
|
|
||||||
|
|
||||||
|
class SkippingClassTestCase(TestCase):
|
||||||
|
def test_skip_class_unless_db_feature(self):
|
||||||
|
@skipUnlessDBFeature("__class__")
|
||||||
|
class NotSkippedTests(unittest.TestCase):
|
||||||
|
def test_dummy(self):
|
||||||
|
return
|
||||||
|
|
||||||
|
@skipIfDBFeature("__class__")
|
||||||
|
class SkippedTests(unittest.TestCase):
|
||||||
|
def test_will_be_skipped(self):
|
||||||
|
self.fail("We should never arrive here.")
|
||||||
|
|
||||||
|
test_suite = unittest.TestSuite()
|
||||||
|
test_suite.addTest(NotSkippedTests('test_dummy'))
|
||||||
|
try:
|
||||||
|
test_suite.addTest(SkippedTests('test_will_be_skipped'))
|
||||||
|
except unittest.SkipTest:
|
||||||
|
self.fail("SkipTest should not be raised at this stage")
|
||||||
|
result = unittest.TextTestRunner(stream=six.StringIO()).run(test_suite)
|
||||||
|
self.assertEqual(result.testsRun, 2)
|
||||||
|
self.assertEqual(len(result.skipped), 1)
|
||||||
|
|
||||||
|
|
||||||
class AssertNumQueriesTests(TestCase):
|
class AssertNumQueriesTests(TestCase):
|
||||||
urls = 'test_utils.urls'
|
urls = 'test_utils.urls'
|
||||||
|
|
||||||
|
@ -561,7 +583,7 @@ class SkippingExtraTests(TestCase):
|
||||||
with self.assertNumQueries(0):
|
with self.assertNumQueries(0):
|
||||||
super(SkippingExtraTests, self).__call__(result)
|
super(SkippingExtraTests, self).__call__(result)
|
||||||
|
|
||||||
@skip("Fixture loading should not be performed for skipped tests.")
|
@unittest.skip("Fixture loading should not be performed for skipped tests.")
|
||||||
def test_fixtures_are_skipped(self):
|
def test_fixtures_are_skipped(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue