Fixed #32609 -- Updated runtests.py to support directory path test labels.

For example, with this change, the following now works from the tests
directory:

    $ ./runtests.py view_tests/tests/
This commit is contained in:
Chris Jerdonek 2021-06-08 01:49:11 -07:00 committed by Mariusz Felisiak
parent fa0433d05f
commit de4f620183
3 changed files with 26 additions and 8 deletions

View File

@ -629,8 +629,8 @@ class DiscoverRunner:
assert tests is None
raise RuntimeError(
f'One of the test labels is a path to a file: {label!r}, '
f'which is not supported. Use a dotted module name '
f'instead.'
f'which is not supported. Use a dotted module name or '
f'path to a directory instead.'
)
return tests

View File

@ -10,6 +10,7 @@ import subprocess
import sys
import tempfile
import warnings
from pathlib import Path
try:
import django
@ -142,18 +143,34 @@ def get_test_modules(gis_enabled):
yield test_module
def get_label_module(label):
"""Return the top-level module part for a test label."""
path = Path(label)
if len(path.parts) == 1:
# Interpret the label as a dotted module name.
return label.split('.')[0]
# Otherwise, interpret the label as a path. Check existence first to
# provide a better error message than relative_to() if it doesn't exist.
if not path.exists():
raise RuntimeError(f'Test label path {label} does not exist')
path = path.resolve()
rel_path = path.relative_to(RUNTESTS_DIR)
return rel_path.parts[0]
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.
test_labels_set = set()
label_modules = set()
for label in test_labels:
test_module = label.split('.')[0]
test_labels_set.add(test_module)
test_module = get_label_module(label)
label_modules.add(test_module)
# 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:
if 'gis_tests' in label_modules and not gis_enabled:
print('Aborting: A GIS database backend is required to run gis_tests.')
sys.exit(1)
@ -174,7 +191,8 @@ def get_filtered_test_modules(start_at, start_after, gis_enabled, test_labels=No
# 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
_module_match_label(test_module, label_module) for
label_module in label_modules
):
yield test_module

View File

@ -63,7 +63,7 @@ class DiscoverRunnerTests(SimpleTestCase):
msg = (
"One of the test labels is a path to a file: "
"'test_discover_runner.py', which is not supported. Use a "
"dotted module name instead."
"dotted module name or path to a directory instead."
)
with self.assertRaisesMessage(RuntimeError, msg):
DiscoverRunner().load_tests_for_label('test_discover_runner.py', {})