Fixed #32516 -- Fixed reorder_suite() with duplicates and reverse=True.
This commit is contained in:
parent
98d3fd6102
commit
77e0a35a10
|
@ -779,7 +779,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, reverse=reverse):
|
for test in iter_test_cases(suite):
|
||||||
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
|
||||||
|
@ -787,6 +787,8 @@ def reorder_suite(suite, classes, reverse=False):
|
||||||
test_bin = last_bin
|
test_bin = last_bin
|
||||||
test_bin.add(test)
|
test_bin.add(test)
|
||||||
|
|
||||||
|
if reverse:
|
||||||
|
bins = (reversed(tests) for tests in bins)
|
||||||
suite_class = type(suite)
|
suite_class = type(suite)
|
||||||
return suite_class(itertools.chain(*bins))
|
return suite_class(itertools.chain(*bins))
|
||||||
|
|
||||||
|
|
|
@ -235,16 +235,14 @@ def setup_databases(
|
||||||
return old_names
|
return old_names
|
||||||
|
|
||||||
|
|
||||||
def iter_test_cases(suite, reverse=False):
|
def iter_test_cases(suite):
|
||||||
"""Return an iterator over a test suite's unittest.TestCase objects."""
|
"""Return an iterator over a test suite's unittest.TestCase objects."""
|
||||||
if reverse:
|
|
||||||
suite = reversed(tuple(suite))
|
|
||||||
for test in suite:
|
for test in suite:
|
||||||
if isinstance(test, TestCase):
|
if isinstance(test, TestCase):
|
||||||
yield test
|
yield test
|
||||||
else:
|
else:
|
||||||
# Otherwise, assume it is a test suite.
|
# Otherwise, assume it is a test suite.
|
||||||
yield from iter_test_cases(test, reverse=reverse)
|
yield from iter_test_cases(test)
|
||||||
|
|
||||||
|
|
||||||
def dependency_ordered(test_databases, dependencies):
|
def dependency_ordered(test_databases, dependencies):
|
||||||
|
|
|
@ -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
|
from django.test.runner import DiscoverRunner, reorder_suite
|
||||||
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,
|
||||||
|
@ -36,13 +36,25 @@ class MySuite:
|
||||||
yield from self.tests
|
yield from self.tests
|
||||||
|
|
||||||
|
|
||||||
class IterTestCasesTests(unittest.TestCase):
|
class TestSuiteTests(unittest.TestCase):
|
||||||
def make_test_suite(self, suite=None, suite_class=None):
|
def build_test_suite(self, test_classes, suite=None, suite_class=None):
|
||||||
if suite_class is None:
|
if suite_class is None:
|
||||||
suite_class = unittest.TestSuite
|
suite_class = unittest.TestSuite
|
||||||
if suite is None:
|
if suite is None:
|
||||||
suite = suite_class()
|
suite = suite_class()
|
||||||
|
|
||||||
|
loader = unittest.defaultTestLoader
|
||||||
|
for test_class in test_classes:
|
||||||
|
tests = loader.loadTestsFromTestCase(test_class)
|
||||||
|
subsuite = suite_class()
|
||||||
|
# Only use addTest() to simplify testing a custom TestSuite.
|
||||||
|
for test in tests:
|
||||||
|
subsuite.addTest(test)
|
||||||
|
suite.addTest(subsuite)
|
||||||
|
|
||||||
|
return suite
|
||||||
|
|
||||||
|
def make_test_suite(self, suite=None, suite_class=None):
|
||||||
class Tests1(unittest.TestCase):
|
class Tests1(unittest.TestCase):
|
||||||
def test1(self):
|
def test1(self):
|
||||||
pass
|
pass
|
||||||
|
@ -57,16 +69,11 @@ class IterTestCasesTests(unittest.TestCase):
|
||||||
def test2(self):
|
def test2(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
loader = unittest.defaultTestLoader
|
return self.build_test_suite(
|
||||||
for test_cls in (Tests1, Tests2):
|
(Tests1, Tests2),
|
||||||
tests = loader.loadTestsFromTestCase(test_cls)
|
suite=suite,
|
||||||
subsuite = suite_class()
|
suite_class=suite_class,
|
||||||
# Only use addTest() to simplify testing a custom TestSuite.
|
)
|
||||||
for test in tests:
|
|
||||||
subsuite.addTest(test)
|
|
||||||
suite.addTest(subsuite)
|
|
||||||
|
|
||||||
return suite
|
|
||||||
|
|
||||||
def assertTestNames(self, tests, expected):
|
def assertTestNames(self, tests, expected):
|
||||||
# Each test.id() has a form like the following:
|
# Each test.id() has a form like the following:
|
||||||
|
@ -75,28 +82,21 @@ class IterTestCasesTests(unittest.TestCase):
|
||||||
names = ['.'.join(test.id().split('.')[-2:]) for test in tests]
|
names = ['.'.join(test.id().split('.')[-2:]) for test in tests]
|
||||||
self.assertEqual(names, expected)
|
self.assertEqual(names, expected)
|
||||||
|
|
||||||
def test_basic(self):
|
def test_iter_test_cases_basic(self):
|
||||||
suite = self.make_test_suite()
|
suite = self.make_test_suite()
|
||||||
tests = iter_test_cases(suite)
|
tests = iter_test_cases(suite)
|
||||||
self.assertTestNames(tests, expected=[
|
self.assertTestNames(tests, expected=[
|
||||||
'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2',
|
'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_reverse(self):
|
def test_iter_test_cases_custom_test_suite_class(self):
|
||||||
suite = self.make_test_suite()
|
|
||||||
tests = iter_test_cases(suite, reverse=True)
|
|
||||||
self.assertTestNames(tests, expected=[
|
|
||||||
'Tests2.test2', 'Tests2.test1', 'Tests1.test2', 'Tests1.test1',
|
|
||||||
])
|
|
||||||
|
|
||||||
def test_custom_test_suite_class(self):
|
|
||||||
suite = self.make_test_suite(suite_class=MySuite)
|
suite = self.make_test_suite(suite_class=MySuite)
|
||||||
tests = iter_test_cases(suite)
|
tests = iter_test_cases(suite)
|
||||||
self.assertTestNames(tests, expected=[
|
self.assertTestNames(tests, expected=[
|
||||||
'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2',
|
'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2',
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_mixed_test_suite_classes(self):
|
def test_iter_test_cases_mixed_test_suite_classes(self):
|
||||||
suite = self.make_test_suite(suite=MySuite())
|
suite = self.make_test_suite(suite=MySuite())
|
||||||
child_suite = list(suite)[0]
|
child_suite = list(suite)[0]
|
||||||
self.assertNotIsInstance(child_suite, MySuite)
|
self.assertNotIsInstance(child_suite, MySuite)
|
||||||
|
@ -104,6 +104,33 @@ class IterTestCasesTests(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):
|
||||||
|
class Tests1(unittest.TestCase):
|
||||||
|
def test1(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Tests2(unittest.TestCase):
|
||||||
|
def test2(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test3(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
suite = self.build_test_suite((Tests1, Tests2))
|
||||||
|
subsuite = list(suite)[0]
|
||||||
|
suite.addTest(subsuite)
|
||||||
|
self.assertTestNames(iter_test_cases(suite), expected=[
|
||||||
|
'Tests1.test1', 'Tests2.test2', 'Tests2.test3', 'Tests1.test1',
|
||||||
|
])
|
||||||
|
reordered_suite = reorder_suite(suite, classes=[])
|
||||||
|
self.assertTestNames(reordered_suite, expected=[
|
||||||
|
'Tests1.test1', 'Tests2.test2', 'Tests2.test3',
|
||||||
|
])
|
||||||
|
reordered_suite = reorder_suite(suite, classes=[], reverse=True)
|
||||||
|
self.assertTestNames(reordered_suite, expected=[
|
||||||
|
'Tests2.test3', 'Tests2.test2', 'Tests1.test1',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
class DependencyOrderingTests(unittest.TestCase):
|
class DependencyOrderingTests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue