Commit 6d52844b authored by Claude Paroz's avatar Claude Paroz
Browse files

Fixed #18551 -- Enabled skipIfDBFeature/skipUnlessDBFeature to decorate a class

Thanks Tim Graham for the review and improved patch.
parent a269ea4f
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -879,10 +879,19 @@ class TestCase(TransactionTestCase):
            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 decorator(test_func):
        if not (isinstance(test_func, type) and
                issubclass(test_func, TestCase)):
                issubclass(test_func, unittest.TestCase)):
            @wraps(test_func)
            def skip_wrapper(*args, **kwargs):
                if condition():
@@ -890,7 +899,9 @@ def _deferredSkip(condition, reason):
                return test_func(*args, **kwargs)
            test_item = skip_wrapper
        else:
            # Assume a class is decorated
            test_item = test_func
            test_item.__unittest_skip__ = CheckCondition(condition)
        test_item.__unittest_skip_why__ = reason
        return test_item
    return decorator
+11 −2
Original line number Diff line number Diff line
@@ -1804,7 +1804,8 @@ for skipping tests.

.. 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
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):
            # ... conditional test code

.. versionchanged:: 1.7

    ``skipIfDBFeature`` can now be used to decorate a ``TestCase`` class.

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

For example, the following test will only be executed if the database
@@ -1828,3 +1833,7 @@ under MySQL with MyISAM tables)::
        @skipUnlessDBFeature('supports_transactions')
        def test_transaction_behavior(self):
            # ... conditional test code

.. versionchanged:: 1.7

    ``skipUnlessDBFeature`` can now be used to decorate a ``TestCase`` class.
+25 −3
Original line number Diff line number Diff line
@@ -2,13 +2,12 @@
from __future__ import absolute_import, unicode_literals

import unittest
from unittest import skip

from django.db import connection
from django.forms import EmailField, IntegerField
from django.http import HttpResponse
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.utils import CaptureQueriesContext, IgnoreAllDeprecationWarningsMixin
from django.utils import six
@@ -27,6 +26,29 @@ class SkippingTestCase(TestCase):
        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):
    urls = 'test_utils.urls'

@@ -561,7 +583,7 @@ class SkippingExtraTests(TestCase):
        with self.assertNumQueries(0):
            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):
        pass