In Python 3.3, if there are duplicate test ids, tests.sort() will
fail and raise TypeError. Detect the duplicate test ids firstly in sorted_tests() to ensure that all test ids are unique.
This commit is contained in:
		
							
								
								
									
										5
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								NEWS
									
									
									
									
									
								
							@@ -13,6 +13,11 @@ Improvements
 | 
			
		||||
* ``AnyMatch`` is now exported properly in ``testtools.matchers``.
 | 
			
		||||
  (Robert Collins, Rob Kennedy, github #44)
 | 
			
		||||
 | 
			
		||||
* In Python 3.3, if there are duplicate test ids, tests.sort() will
 | 
			
		||||
  fail and raise TypeError. Detect the duplicate test ids firstly in
 | 
			
		||||
  sorted_tests() to ensure that all test ids are unique.
 | 
			
		||||
  (Kui Shi, #1243922)
 | 
			
		||||
 | 
			
		||||
* ``json_content`` is now in the ``__all__`` attribute for
 | 
			
		||||
  ``testtools.content``. (Robert Collins)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -429,6 +429,8 @@ sort_tests, which can be used by non-standard TestSuites to know when they
 | 
			
		||||
should sort their tests. An example implementation can be seen at
 | 
			
		||||
``FixtureSuite.sorted_tests``.
 | 
			
		||||
 | 
			
		||||
If there are duplicate test ids in a suite, ValueError will be raised.
 | 
			
		||||
 | 
			
		||||
filter_by_ids
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -224,6 +224,19 @@ class TestFixtureSuite(TestCase):
 | 
			
		||||
        suite.run(LoggingResult([]))
 | 
			
		||||
        self.assertEqual(['setUp', 1, 2, 'tearDown'], log)
 | 
			
		||||
 | 
			
		||||
    def test_fixture_suite_sort(self):
 | 
			
		||||
        log = []
 | 
			
		||||
        class Sample(TestCase):
 | 
			
		||||
            def test_one(self):
 | 
			
		||||
                log.append(1)
 | 
			
		||||
            def test_two(self):
 | 
			
		||||
                log.append(2)
 | 
			
		||||
        fixture = FunctionFixture(
 | 
			
		||||
            lambda: log.append('setUp'),
 | 
			
		||||
            lambda fixture: log.append('tearDown'))
 | 
			
		||||
        suite = FixtureSuite(fixture, [Sample('test_one'), Sample('test_one')])
 | 
			
		||||
        self.assertRaises(ValueError, suite.sort_tests)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestSortedTests(TestCase):
 | 
			
		||||
 | 
			
		||||
@@ -253,6 +266,13 @@ class TestSortedTests(TestCase):
 | 
			
		||||
        suite = sorted_tests(unittest.TestSuite([b, a]))
 | 
			
		||||
        self.assertEqual([a, b], list(iterate_tests(suite)))
 | 
			
		||||
 | 
			
		||||
    def test_duplicate_simple_suites(self):
 | 
			
		||||
        a = PlaceHolder('a')
 | 
			
		||||
        b = PlaceHolder('b')
 | 
			
		||||
        c = PlaceHolder('a')
 | 
			
		||||
        self.assertRaises(
 | 
			
		||||
            ValueError, sorted_tests, unittest.TestSuite([a, b, c]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_suite():
 | 
			
		||||
    from unittest import TestLoader
 | 
			
		||||
 
 | 
			
		||||
@@ -303,6 +303,15 @@ def filter_by_ids(suite_or_case, test_ids):
 | 
			
		||||
 | 
			
		||||
def sorted_tests(suite_or_case, unpack_outer=False):
 | 
			
		||||
    """Sort suite_or_case while preserving non-vanilla TestSuites."""
 | 
			
		||||
    # Duplicate test id can induce TypeError in Python 3.3.
 | 
			
		||||
    # Detect the duplicate test id, raise exception when found.
 | 
			
		||||
    seen = set()
 | 
			
		||||
    for test_case in iterate_tests(suite_or_case):
 | 
			
		||||
        test_id = test_case.id()
 | 
			
		||||
        if test_id not in seen:
 | 
			
		||||
            seen.add(test_id)
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError('Duplicate test id detected: %s' % (test_id,))
 | 
			
		||||
    tests = _flatten_tests(suite_or_case, unpack_outer=unpack_outer)
 | 
			
		||||
    tests.sort()
 | 
			
		||||
    return unittest.TestSuite([test for (sort_key, test) in tests])
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user