summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2021-06-03 22:03:34 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-06-07 09:04:24 +0200
commitb3083d5bd244ca90848aaa2a1c8e7ba7f9cc72f4 (patch)
tree58371c8675d264ddfa5b432c11cd76f83bf660f7 /tests
parent9b9cea04b98b66a68b7588cc4c34401f5f7d7c12 (diff)
Refs #32668 -- Refactored out setup_collect_tests() in runtests.py.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/runtests.py120
1 files changed, 69 insertions, 51 deletions
diff --git a/tests/runtests.py b/tests/runtests.py
index 16942e249b..fe5642bbf5 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -142,11 +142,7 @@ def get_test_modules(gis_enabled):
yield test_module
-def get_installed():
- return [app_config.name for app_config in apps.get_app_configs()]
-
-
-def setup(verbosity, start_at, start_after, test_labels=None):
+def get_filtered_test_modules(start_at, start_after, gis_enabled, test_labels=None):
if test_labels is None:
test_labels = []
# Reduce each test label to just the top-level module part.
@@ -155,13 +151,35 @@ def setup(verbosity, start_at, start_after, test_labels=None):
test_module = label.split('.')[0]
test_labels_set.add(test_module)
- # Force declaring available_apps in TransactionTestCase for faster tests.
- def no_available_apps(self):
- raise Exception("Please define available_apps in TransactionTestCase "
- "and its subclasses.")
- TransactionTestCase.available_apps = property(no_available_apps)
- TestCase.available_apps = None
+ # It would be nice to put this validation earlier but it must come after
+ # django.setup() so that connection.features.gis_enabled can be accessed.
+ if 'gis_tests' in test_labels_set and not gis_enabled:
+ print('Aborting: A GIS database backend is required to run gis_tests.')
+ sys.exit(1)
+
+ def _module_match_label(module_name, label):
+ # Exact or ancestor match.
+ return module_name == label or module_name.startswith(label + '.')
+ start_label = start_at or start_after
+ for test_module in get_test_modules(gis_enabled):
+ if start_label:
+ if not _module_match_label(test_module, start_label):
+ continue
+ start_label = ''
+ if not start_at:
+ assert start_after
+ # Skip the current one before starting.
+ continue
+ # If the module (or an ancestor) was named on the command line, or
+ # no modules were named (i.e., run all), include the test module.
+ if not test_labels or any(
+ _module_match_label(test_module, label) for label in test_labels_set
+ ):
+ yield test_module
+
+
+def setup_collect_tests(start_at, start_after, test_labels=None):
state = {
'INSTALLED_APPS': settings.INSTALLED_APPS,
'ROOT_URLCONF': getattr(settings, "ROOT_URLCONF", ""),
@@ -212,58 +230,58 @@ def setup(verbosity, start_at, start_after, test_labels=None):
# Load all the ALWAYS_INSTALLED_APPS.
django.setup()
- # It would be nice to put this validation earlier but it must come after
- # django.setup() so that connection.features.gis_enabled can be accessed
- # without raising AppRegistryNotReady when running gis_tests in isolation
- # on some backends (e.g. PostGIS).
+ # This flag must be evaluated after django.setup() because otherwise it can
+ # raise AppRegistryNotReady when running gis_tests in isolation on some
+ # backends (e.g. PostGIS).
gis_enabled = connection.features.gis_enabled
- if 'gis_tests' in test_labels_set and not gis_enabled:
- print('Aborting: A GIS database backend is required to run gis_tests.')
- sys.exit(1)
- def _module_match_label(module_name, label):
- # Exact or ancestor match.
- return module_name == label or module_name.startswith(label + '.')
+ test_modules = list(get_filtered_test_modules(
+ start_at, start_after, gis_enabled, test_labels=test_labels,
+ ))
+ return test_modules, state
- start_label = start_at or start_after
- installed_app_names = set(get_installed())
- for test_module in get_test_modules(gis_enabled):
- if start_label:
- if not _module_match_label(test_module, start_label):
- continue
- start_label = ''
- if not start_at:
- assert start_after
- # Skip the current one before starting.
- continue
- # if the module (or an ancestor) was named on the command line, or
- # no modules were named (i.e., run all), import
- # this module and add it to INSTALLED_APPS.
- if test_labels and not any(
- _module_match_label(test_module, label) for label in test_labels_set
- ):
- continue
- if test_module in CONTRIB_TESTS_TO_APPS:
- for contrib_app in CONTRIB_TESTS_TO_APPS[test_module]:
- if contrib_app not in settings.INSTALLED_APPS:
- settings.INSTALLED_APPS.append(contrib_app)
+def get_installed():
+ return [app_config.name for app_config in apps.get_app_configs()]
+
- if test_module not in installed_app_names:
- if verbosity >= 2:
- print("Importing application %s" % test_module)
- settings.INSTALLED_APPS.append(test_module)
+# This function should be called only after calling django.setup(),
+# since it calls connection.features.gis_enabled.
+def get_apps_to_install(test_modules):
+ for test_module in test_modules:
+ if test_module in CONTRIB_TESTS_TO_APPS:
+ yield from CONTRIB_TESTS_TO_APPS[test_module]
+ yield test_module
# Add contrib.gis to INSTALLED_APPS if needed (rather than requiring
# @override_settings(INSTALLED_APPS=...) on all test cases.
- gis = 'django.contrib.gis'
- if connection.features.gis_enabled and gis not in settings.INSTALLED_APPS:
+ if connection.features.gis_enabled:
+ yield 'django.contrib.gis'
+
+
+def setup(verbosity, start_at, start_after, test_labels=None):
+ test_modules, state = setup_collect_tests(start_at, start_after, test_labels=test_labels)
+
+ installed_apps = set(get_installed())
+ for app in get_apps_to_install(test_modules):
+ if app in installed_apps:
+ continue
if verbosity >= 2:
- print("Importing application %s" % gis)
- settings.INSTALLED_APPS.append(gis)
+ print(f'Importing application {app}')
+ settings.INSTALLED_APPS.append(app)
+ installed_apps.add(app)
apps.set_installed_apps(settings.INSTALLED_APPS)
+ # Force declaring available_apps in TransactionTestCase for faster tests.
+ def no_available_apps(self):
+ raise Exception(
+ 'Please define available_apps in TransactionTestCase and its '
+ 'subclasses.'
+ )
+ TransactionTestCase.available_apps = property(no_available_apps)
+ TestCase.available_apps = None
+
# Set an environment variable that other code may consult to see if
# Django's own test suite is running.
os.environ['RUNNING_DJANGOS_TEST_SUITE'] = 'true'