Fixed #32529 -- Delayed creating a test suite in build_suite().
This commit is contained in:
parent
d8a4bcffdb
commit
d828beb68f
|
@ -553,7 +553,6 @@ class DiscoverRunner:
|
||||||
unittest.installHandler()
|
unittest.installHandler()
|
||||||
|
|
||||||
def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
|
def build_suite(self, test_labels=None, extra_tests=None, **kwargs):
|
||||||
suite = self.test_suite()
|
|
||||||
test_labels = test_labels or ['.']
|
test_labels = test_labels or ['.']
|
||||||
extra_tests = extra_tests or []
|
extra_tests = extra_tests or []
|
||||||
self.test_loader.testNamePatterns = self.test_name_patterns
|
self.test_loader.testNamePatterns = self.test_name_patterns
|
||||||
|
@ -564,6 +563,7 @@ class DiscoverRunner:
|
||||||
if self.top_level is not None:
|
if self.top_level is not None:
|
||||||
discover_kwargs['top_level_dir'] = self.top_level
|
discover_kwargs['top_level_dir'] = self.top_level
|
||||||
|
|
||||||
|
all_tests = []
|
||||||
for label in test_labels:
|
for label in test_labels:
|
||||||
kwargs = discover_kwargs.copy()
|
kwargs = discover_kwargs.copy()
|
||||||
tests = None
|
tests = None
|
||||||
|
@ -607,10 +607,9 @@ class DiscoverRunner:
|
||||||
# run, to support running tests from two different top-levels.
|
# run, to support running tests from two different top-levels.
|
||||||
self.test_loader._top_level_dir = None
|
self.test_loader._top_level_dir = None
|
||||||
|
|
||||||
suite.addTests(tests)
|
all_tests.extend(iter_test_cases(tests))
|
||||||
|
|
||||||
for test in extra_tests:
|
all_tests.extend(iter_test_cases(extra_tests))
|
||||||
suite.addTest(test)
|
|
||||||
|
|
||||||
if self.tags or self.exclude_tags:
|
if self.tags or self.exclude_tags:
|
||||||
if self.verbosity >= 2:
|
if self.verbosity >= 2:
|
||||||
|
@ -618,8 +617,10 @@ class DiscoverRunner:
|
||||||
print('Including test tag(s): %s.' % ', '.join(sorted(self.tags)))
|
print('Including test tag(s): %s.' % ', '.join(sorted(self.tags)))
|
||||||
if self.exclude_tags:
|
if self.exclude_tags:
|
||||||
print('Excluding test tag(s): %s.' % ', '.join(sorted(self.exclude_tags)))
|
print('Excluding test tag(s): %s.' % ', '.join(sorted(self.exclude_tags)))
|
||||||
suite = filter_tests_by_tags(suite, self.tags, self.exclude_tags)
|
all_tests = filter_tests_by_tags(all_tests, self.tags, self.exclude_tags)
|
||||||
suite = reorder_suite(suite, self.reorder_by, self.reverse)
|
|
||||||
|
all_tests = reorder_tests(all_tests, self.reorder_by, self.reverse)
|
||||||
|
suite = self.test_suite(all_tests)
|
||||||
|
|
||||||
if self.parallel > 1:
|
if self.parallel > 1:
|
||||||
parallel_suite = self.parallel_test_suite(suite, self.parallel, self.failfast)
|
parallel_suite = self.parallel_test_suite(suite, self.parallel, self.failfast)
|
||||||
|
@ -764,11 +765,11 @@ def is_discoverable(label):
|
||||||
return os.path.isdir(os.path.abspath(label))
|
return os.path.isdir(os.path.abspath(label))
|
||||||
|
|
||||||
|
|
||||||
def reorder_suite(suite, classes, reverse=False):
|
def reorder_tests(tests, classes, reverse=False):
|
||||||
"""
|
"""
|
||||||
Reorder a test suite by test type, removing any duplicates.
|
Reorder an iterable of tests by test type, removing any duplicates.
|
||||||
|
|
||||||
`classes` is a sequence of types
|
`classes` is a sequence of types. The result is returned as an iterator.
|
||||||
|
|
||||||
All tests of type classes[0] are placed first, then tests of type
|
All tests of type classes[0] are placed first, then tests of type
|
||||||
classes[1], etc. Tests with no match in classes are placed last.
|
classes[1], etc. Tests with no match in classes are placed last.
|
||||||
|
@ -779,7 +780,7 @@ def reorder_suite(suite, classes, reverse=False):
|
||||||
bins = [OrderedSet() for i in range(len(classes) + 1)]
|
bins = [OrderedSet() for i in range(len(classes) + 1)]
|
||||||
*class_bins, last_bin = bins
|
*class_bins, last_bin = bins
|
||||||
|
|
||||||
for test in iter_test_cases(suite):
|
for test in tests:
|
||||||
for test_bin, test_class in zip(class_bins, classes):
|
for test_bin, test_class in zip(class_bins, classes):
|
||||||
if isinstance(test, test_class):
|
if isinstance(test, test_class):
|
||||||
break
|
break
|
||||||
|
@ -789,8 +790,7 @@ def reorder_suite(suite, classes, reverse=False):
|
||||||
|
|
||||||
if reverse:
|
if reverse:
|
||||||
bins = (reversed(tests) for tests in bins)
|
bins = (reversed(tests) for tests in bins)
|
||||||
suite_class = type(suite)
|
return itertools.chain(*bins)
|
||||||
return suite_class(itertools.chain(*bins))
|
|
||||||
|
|
||||||
|
|
||||||
def partition_suite_by_case(suite):
|
def partition_suite_by_case(suite):
|
||||||
|
@ -813,9 +813,6 @@ def test_match_tags(test, tags, exclude_tags):
|
||||||
return (matched_tags or not tags) and not test_tags.intersection(exclude_tags)
|
return (matched_tags or not tags) and not test_tags.intersection(exclude_tags)
|
||||||
|
|
||||||
|
|
||||||
def filter_tests_by_tags(suite, tags, exclude_tags):
|
def filter_tests_by_tags(tests, tags, exclude_tags):
|
||||||
suite_class = type(suite)
|
"""Return the matching tests as an iterator."""
|
||||||
return suite_class(
|
return (test for test in tests if test_match_tags(test, tags, exclude_tags))
|
||||||
test for test in iter_test_cases(suite)
|
|
||||||
if test_match_tags(test, tags, exclude_tags)
|
|
||||||
)
|
|
||||||
|
|
|
@ -321,6 +321,10 @@ Miscellaneous
|
||||||
* Unsupported operations on a sliced queryset now raise ``TypeError`` instead
|
* Unsupported operations on a sliced queryset now raise ``TypeError`` instead
|
||||||
of ``AssertionError``.
|
of ``AssertionError``.
|
||||||
|
|
||||||
|
* The undocumented ``django.test.runner.reorder_suite()`` function is renamed
|
||||||
|
to ``reorder_tests()``. It now accepts an iterable of tests rather than a
|
||||||
|
test suite, and returns an iterator of tests.
|
||||||
|
|
||||||
.. _deprecated-features-4.0:
|
.. _deprecated-features-4.0:
|
||||||
|
|
||||||
Features deprecated in 4.0
|
Features deprecated in 4.0
|
||||||
|
|
|
@ -14,7 +14,7 @@ from django.core.management.base import SystemCheckError
|
||||||
from django.test import (
|
from django.test import (
|
||||||
SimpleTestCase, TransactionTestCase, skipUnlessDBFeature,
|
SimpleTestCase, TransactionTestCase, skipUnlessDBFeature,
|
||||||
)
|
)
|
||||||
from django.test.runner import DiscoverRunner, reorder_suite
|
from django.test.runner import DiscoverRunner, reorder_tests
|
||||||
from django.test.testcases import connections_support_transactions
|
from django.test.testcases import connections_support_transactions
|
||||||
from django.test.utils import (
|
from django.test.utils import (
|
||||||
captured_stderr, dependency_ordered, get_unique_databases_and_mirrors,
|
captured_stderr, dependency_ordered, get_unique_databases_and_mirrors,
|
||||||
|
@ -118,7 +118,7 @@ class TestSuiteTests(unittest.TestCase):
|
||||||
self.assertEqual(len(tests), 4)
|
self.assertEqual(len(tests), 4)
|
||||||
self.assertNotIsInstance(tests[0], unittest.TestSuite)
|
self.assertNotIsInstance(tests[0], unittest.TestSuite)
|
||||||
|
|
||||||
def test_reorder_suite_reverse_with_duplicates(self):
|
def test_reorder_tests_reverse_with_duplicates(self):
|
||||||
class Tests1(unittest.TestCase):
|
class Tests1(unittest.TestCase):
|
||||||
def test1(self):
|
def test1(self):
|
||||||
pass
|
pass
|
||||||
|
@ -133,15 +133,16 @@ class TestSuiteTests(unittest.TestCase):
|
||||||
suite = self.build_test_suite((Tests1, Tests2))
|
suite = self.build_test_suite((Tests1, Tests2))
|
||||||
subsuite = list(suite)[0]
|
subsuite = list(suite)[0]
|
||||||
suite.addTest(subsuite)
|
suite.addTest(subsuite)
|
||||||
self.assertTestNames(iter_test_cases(suite), expected=[
|
tests = list(iter_test_cases(suite))
|
||||||
|
self.assertTestNames(tests, expected=[
|
||||||
'Tests1.test1', 'Tests2.test2', 'Tests2.test3', 'Tests1.test1',
|
'Tests1.test1', 'Tests2.test2', 'Tests2.test3', 'Tests1.test1',
|
||||||
])
|
])
|
||||||
reordered_suite = reorder_suite(suite, classes=[])
|
reordered_tests = reorder_tests(tests, classes=[])
|
||||||
self.assertTestNames(reordered_suite, expected=[
|
self.assertTestNames(reordered_tests, expected=[
|
||||||
'Tests1.test1', 'Tests2.test2', 'Tests2.test3',
|
'Tests1.test1', 'Tests2.test2', 'Tests2.test3',
|
||||||
])
|
])
|
||||||
reordered_suite = reorder_suite(suite, classes=[], reverse=True)
|
reordered_tests = reorder_tests(tests, classes=[], reverse=True)
|
||||||
self.assertTestNames(reordered_suite, expected=[
|
self.assertTestNames(reordered_tests, expected=[
|
||||||
'Tests2.test3', 'Tests2.test2', 'Tests1.test1',
|
'Tests2.test3', 'Tests2.test2', 'Tests1.test1',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue