mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							fa0433d05f
						
					
				
				
					commit
					de4f620183
				
			| @@ -629,8 +629,8 @@ class DiscoverRunner: | |||||||
|                 assert tests is None |                 assert tests is None | ||||||
|                 raise RuntimeError( |                 raise RuntimeError( | ||||||
|                     f'One of the test labels is a path to a file: {label!r}, ' |                     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'which is not supported. Use a dotted module name or ' | ||||||
|                     f'instead.' |                     f'path to a directory instead.' | ||||||
|                 ) |                 ) | ||||||
|             return tests |             return tests | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import subprocess | |||||||
| import sys | import sys | ||||||
| import tempfile | import tempfile | ||||||
| import warnings | import warnings | ||||||
|  | from pathlib import Path | ||||||
|  |  | ||||||
| try: | try: | ||||||
|     import django |     import django | ||||||
| @@ -142,18 +143,34 @@ def get_test_modules(gis_enabled): | |||||||
|                 yield test_module |                 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): | def get_filtered_test_modules(start_at, start_after, gis_enabled, 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. | ||||||
|     test_labels_set = set() |     label_modules = set() | ||||||
|     for label in test_labels: |     for label in test_labels: | ||||||
|         test_module = label.split('.')[0] |         test_module = get_label_module(label) | ||||||
|         test_labels_set.add(test_module) |         label_modules.add(test_module) | ||||||
|  |  | ||||||
|     # It would be nice to put this validation earlier but it must come after |     # 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. |     # 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.') |         print('Aborting: A GIS database backend is required to run gis_tests.') | ||||||
|         sys.exit(1) |         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 |         # 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. |         # no modules were named (i.e., run all), include the test module. | ||||||
|         if not test_labels or any( |         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 |             yield test_module | ||||||
|  |  | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ class DiscoverRunnerTests(SimpleTestCase): | |||||||
|             msg = ( |             msg = ( | ||||||
|                 "One of the test labels is a path to a file: " |                 "One of the test labels is a path to a file: " | ||||||
|                 "'test_discover_runner.py', which is not supported. Use a " |                 "'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): |             with self.assertRaisesMessage(RuntimeError, msg): | ||||||
|                 DiscoverRunner().load_tests_for_label('test_discover_runner.py', {}) |                 DiscoverRunner().load_tests_for_label('test_discover_runner.py', {}) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user