Refs #32668 -- Refactored out setup_collect_tests() in runtests.py.
This commit is contained in:
parent
9b9cea04b9
commit
b3083d5bd2
|
@ -142,11 +142,7 @@ def get_test_modules(gis_enabled):
|
||||||
yield test_module
|
yield test_module
|
||||||
|
|
||||||
|
|
||||||
def get_installed():
|
def get_filtered_test_modules(start_at, start_after, gis_enabled, test_labels=None):
|
||||||
return [app_config.name for app_config in apps.get_app_configs()]
|
|
||||||
|
|
||||||
|
|
||||||
def setup(verbosity, start_at, start_after, test_labels=None):
|
|
||||||
if test_labels is None:
|
if test_labels is None:
|
||||||
test_labels = []
|
test_labels = []
|
||||||
# Reduce each test label to just the top-level module part.
|
# 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_module = label.split('.')[0]
|
||||||
test_labels_set.add(test_module)
|
test_labels_set.add(test_module)
|
||||||
|
|
||||||
# Force declaring available_apps in TransactionTestCase for faster tests.
|
# It would be nice to put this validation earlier but it must come after
|
||||||
def no_available_apps(self):
|
# django.setup() so that connection.features.gis_enabled can be accessed.
|
||||||
raise Exception("Please define available_apps in TransactionTestCase "
|
if 'gis_tests' in test_labels_set and not gis_enabled:
|
||||||
"and its subclasses.")
|
print('Aborting: A GIS database backend is required to run gis_tests.')
|
||||||
TransactionTestCase.available_apps = property(no_available_apps)
|
sys.exit(1)
|
||||||
TestCase.available_apps = None
|
|
||||||
|
|
||||||
|
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 = {
|
state = {
|
||||||
'INSTALLED_APPS': settings.INSTALLED_APPS,
|
'INSTALLED_APPS': settings.INSTALLED_APPS,
|
||||||
'ROOT_URLCONF': getattr(settings, "ROOT_URLCONF", ""),
|
'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.
|
# Load all the ALWAYS_INSTALLED_APPS.
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
# It would be nice to put this validation earlier but it must come after
|
# This flag must be evaluated after django.setup() because otherwise it can
|
||||||
# django.setup() so that connection.features.gis_enabled can be accessed
|
# raise AppRegistryNotReady when running gis_tests in isolation on some
|
||||||
# without raising AppRegistryNotReady when running gis_tests in isolation
|
# backends (e.g. PostGIS).
|
||||||
# on some backends (e.g. PostGIS).
|
|
||||||
gis_enabled = connection.features.gis_enabled
|
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):
|
test_modules = list(get_filtered_test_modules(
|
||||||
# Exact or ancestor match.
|
start_at, start_after, gis_enabled, test_labels=test_labels,
|
||||||
return module_name == label or module_name.startswith(label + '.')
|
))
|
||||||
|
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
|
|
||||||
|
|
||||||
|
def get_installed():
|
||||||
|
return [app_config.name for app_config in apps.get_app_configs()]
|
||||||
|
|
||||||
|
|
||||||
|
# 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:
|
if test_module in CONTRIB_TESTS_TO_APPS:
|
||||||
for contrib_app in CONTRIB_TESTS_TO_APPS[test_module]:
|
yield from CONTRIB_TESTS_TO_APPS[test_module]
|
||||||
if contrib_app not in settings.INSTALLED_APPS:
|
yield test_module
|
||||||
settings.INSTALLED_APPS.append(contrib_app)
|
|
||||||
|
|
||||||
if test_module not in installed_app_names:
|
|
||||||
if verbosity >= 2:
|
|
||||||
print("Importing application %s" % test_module)
|
|
||||||
settings.INSTALLED_APPS.append(test_module)
|
|
||||||
|
|
||||||
# Add contrib.gis to INSTALLED_APPS if needed (rather than requiring
|
# Add contrib.gis to INSTALLED_APPS if needed (rather than requiring
|
||||||
# @override_settings(INSTALLED_APPS=...) on all test cases.
|
# @override_settings(INSTALLED_APPS=...) on all test cases.
|
||||||
gis = 'django.contrib.gis'
|
if connection.features.gis_enabled:
|
||||||
if connection.features.gis_enabled and gis not in settings.INSTALLED_APPS:
|
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:
|
if verbosity >= 2:
|
||||||
print("Importing application %s" % gis)
|
print(f'Importing application {app}')
|
||||||
settings.INSTALLED_APPS.append(gis)
|
settings.INSTALLED_APPS.append(app)
|
||||||
|
installed_apps.add(app)
|
||||||
|
|
||||||
apps.set_installed_apps(settings.INSTALLED_APPS)
|
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
|
# Set an environment variable that other code may consult to see if
|
||||||
# Django's own test suite is running.
|
# Django's own test suite is running.
|
||||||
os.environ['RUNNING_DJANGOS_TEST_SUITE'] = 'true'
|
os.environ['RUNNING_DJANGOS_TEST_SUITE'] = 'true'
|
||||||
|
|
Loading…
Reference in New Issue