diff options
| author | Simon Charette <charette.s@gmail.com> | 2019-01-12 16:14:54 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2019-01-14 16:16:30 -0500 |
| commit | b181aba7dd24c73ec9923c39e35393b0487a5f47 (patch) | |
| tree | e5d82ea665a4b6eace3e07fb53d78808b936c624 /django | |
| parent | f5b635086a07c9df5897e69685ebdc3a04049ec6 (diff) | |
Refs #28478 -- Prevented database feature based skipping on tests disallowing queries.
Database features may require a connection to be established to determine
whether or not they are enabled.
Diffstat (limited to 'django')
| -rw-r--r-- | django/test/testcases.py | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/django/test/testcases.py b/django/test/testcases.py index 0e1da33064..3dd14a08c0 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -1205,12 +1205,24 @@ class CheckCondition: return False -def _deferredSkip(condition, reason): +def _deferredSkip(condition, reason, name): def decorator(test_func): + nonlocal condition if not (isinstance(test_func, type) and issubclass(test_func, unittest.TestCase)): @wraps(test_func) def skip_wrapper(*args, **kwargs): + if (args and isinstance(args[0], unittest.TestCase) and + connection.alias not in getattr(args[0], 'databases', {})): + raise ValueError( + "%s cannot be used on %s as %s doesn't allow queries " + "against the %r database." % ( + name, + args[0], + args[0].__class__.__qualname__, + connection.alias, + ) + ) if condition(): raise unittest.SkipTest(reason) return test_func(*args, **kwargs) @@ -1218,6 +1230,16 @@ def _deferredSkip(condition, reason): else: # Assume a class is decorated test_item = test_func + databases = getattr(test_item, 'databases', None) + if not databases or connection.alias not in databases: + # Defer raising to allow importing test class's module. + def condition(): + raise ValueError( + "%s cannot be used on %s as it doesn't allow queries " + "against the '%s' database." % ( + name, test_item, connection.alias, + ) + ) # Retrieve the possibly existing value from the class's dict to # avoid triggering the descriptor. skip = test_func.__dict__.get('__unittest_skip__') @@ -1233,7 +1255,8 @@ def skipIfDBFeature(*features): """Skip a test if a database has at least one of the named features.""" return _deferredSkip( lambda: any(getattr(connection.features, feature, False) for feature in features), - "Database has feature(s) %s" % ", ".join(features) + "Database has feature(s) %s" % ", ".join(features), + 'skipIfDBFeature', ) @@ -1241,7 +1264,8 @@ def skipUnlessDBFeature(*features): """Skip a test unless a database has all the named features.""" return _deferredSkip( lambda: not all(getattr(connection.features, feature, False) for feature in features), - "Database doesn't support feature(s): %s" % ", ".join(features) + "Database doesn't support feature(s): %s" % ", ".join(features), + 'skipUnlessDBFeature', ) @@ -1249,7 +1273,8 @@ def skipUnlessAnyDBFeature(*features): """Skip a test unless a database has any of the named features.""" return _deferredSkip( lambda: not any(getattr(connection.features, feature, False) for feature in features), - "Database doesn't support any of the feature(s): %s" % ", ".join(features) + "Database doesn't support any of the feature(s): %s" % ", ".join(features), + 'skipUnlessAnyDBFeature', ) |
