mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #32516 -- Fixed reorder_suite() with duplicates and reverse=True.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							98d3fd6102
						
					
				
				
					commit
					77e0a35a10
				
			| @@ -779,7 +779,7 @@ def reorder_suite(suite, classes, reverse=False): | ||||
|     bins = [OrderedSet() for i in range(len(classes) + 1)] | ||||
|     *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): | ||||
|             if isinstance(test, test_class): | ||||
|                 break | ||||
| @@ -787,6 +787,8 @@ def reorder_suite(suite, classes, reverse=False): | ||||
|             test_bin = last_bin | ||||
|         test_bin.add(test) | ||||
|  | ||||
|     if reverse: | ||||
|         bins = (reversed(tests) for tests in bins) | ||||
|     suite_class = type(suite) | ||||
|     return suite_class(itertools.chain(*bins)) | ||||
|  | ||||
|   | ||||
| @@ -235,16 +235,14 @@ def setup_databases( | ||||
|     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.""" | ||||
|     if reverse: | ||||
|         suite = reversed(tuple(suite)) | ||||
|     for test in suite: | ||||
|         if isinstance(test, TestCase): | ||||
|             yield test | ||||
|         else: | ||||
|             # 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): | ||||
|   | ||||
| @@ -14,7 +14,7 @@ from django.core.management.base import SystemCheckError | ||||
| from django.test import ( | ||||
|     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.utils import ( | ||||
|     captured_stderr, dependency_ordered, get_unique_databases_and_mirrors, | ||||
| @@ -36,13 +36,25 @@ class MySuite: | ||||
|         yield from self.tests | ||||
|  | ||||
|  | ||||
| class IterTestCasesTests(unittest.TestCase): | ||||
|     def make_test_suite(self, suite=None, suite_class=None): | ||||
| class TestSuiteTests(unittest.TestCase): | ||||
|     def build_test_suite(self, test_classes, suite=None, suite_class=None): | ||||
|         if suite_class is None: | ||||
|             suite_class = unittest.TestSuite | ||||
|         if suite is None: | ||||
|             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): | ||||
|             def test1(self): | ||||
|                 pass | ||||
| @@ -57,16 +69,11 @@ class IterTestCasesTests(unittest.TestCase): | ||||
|             def test2(self): | ||||
|                 pass | ||||
|  | ||||
|         loader = unittest.defaultTestLoader | ||||
|         for test_cls in (Tests1, Tests2): | ||||
|             tests = loader.loadTestsFromTestCase(test_cls) | ||||
|             subsuite = suite_class() | ||||
|             # Only use addTest() to simplify testing a custom TestSuite. | ||||
|             for test in tests: | ||||
|                 subsuite.addTest(test) | ||||
|             suite.addTest(subsuite) | ||||
|  | ||||
|         return suite | ||||
|         return self.build_test_suite( | ||||
|             (Tests1, Tests2), | ||||
|             suite=suite, | ||||
|             suite_class=suite_class, | ||||
|         ) | ||||
|  | ||||
|     def assertTestNames(self, tests, expected): | ||||
|         # 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] | ||||
|         self.assertEqual(names, expected) | ||||
|  | ||||
|     def test_basic(self): | ||||
|     def test_iter_test_cases_basic(self): | ||||
|         suite = self.make_test_suite() | ||||
|         tests = iter_test_cases(suite) | ||||
|         self.assertTestNames(tests, expected=[ | ||||
|             'Tests1.test1', 'Tests1.test2', 'Tests2.test1', 'Tests2.test2', | ||||
|         ]) | ||||
|  | ||||
|     def test_reverse(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): | ||||
|     def test_iter_test_cases_custom_test_suite_class(self): | ||||
|         suite = self.make_test_suite(suite_class=MySuite) | ||||
|         tests = iter_test_cases(suite) | ||||
|         self.assertTestNames(tests, expected=[ | ||||
|             '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()) | ||||
|         child_suite = list(suite)[0] | ||||
|         self.assertNotIsInstance(child_suite, MySuite) | ||||
| @@ -104,6 +104,33 @@ class IterTestCasesTests(unittest.TestCase): | ||||
|         self.assertEqual(len(tests), 4) | ||||
|         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): | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user