]> granicus.if.org Git - python/commitdiff
bpo-30664: The description of a unittest subtest now preserves the (#2265)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 23 Jun 2017 18:47:39 +0000 (21:47 +0300)
committerGitHub <noreply@github.com>
Fri, 23 Jun 2017 18:47:39 +0000 (21:47 +0300)
order of keyword arguments of TestCase.subTest().

Lib/unittest/case.py
Lib/unittest/test/test_result.py
Misc/NEWS

index 993aaec1940748cd3b00d2e4cb835a22eb9c0c30..f19afef48d73cd6d48c2221c87777f3fc8671b26 100644 (file)
@@ -338,6 +338,16 @@ class _AssertLogsContext(_BaseTestCaseContext):
                 .format(logging.getLevelName(self.level), self.logger.name))
 
 
+class _OrderedChainMap(collections.ChainMap):
+    def __iter__(self):
+        seen = set()
+        for mapping in self.maps:
+            for k in mapping:
+                if k not in seen:
+                    seen.add(k)
+                    yield k
+
+
 class TestCase(object):
     """A class whose instances are single test cases.
 
@@ -514,7 +524,7 @@ class TestCase(object):
             return
         parent = self._subtest
         if parent is None:
-            params_map = collections.ChainMap(params)
+            params_map = _OrderedChainMap(params)
         else:
             params_map = parent.params.new_child(params)
         self._subtest = _SubTest(self, msg, params_map)
@@ -1418,7 +1428,7 @@ class _SubTest(TestCase):
         if self.params:
             params_desc = ', '.join(
                 "{}={!r}".format(k, v)
-                for (k, v) in sorted(self.params.items()))
+                for (k, v) in self.params.items())
             parts.append("({})".format(params_desc))
         return " ".join(parts) or '(<subtest>)'
 
index 0a6155356373858e7ce9975fc1f8332cf94f0717..0ffb87b40256cff09553e1b2ac945b32dabcf613 100644 (file)
@@ -307,7 +307,7 @@ class Test_TestResult(unittest.TestCase):
             self.assertEqual(
                     result.getDescription(self._subtest),
                     'testGetSubTestDescriptionWithoutDocstring (' + __name__ +
-                    '.Test_TestResult) (bar=2, foo=1)')
+                    '.Test_TestResult) (foo=1, bar=2)')
         with self.subTest('some message'):
             result = unittest.TextTestResult(None, True, 1)
             self.assertEqual(
@@ -335,12 +335,21 @@ class Test_TestResult(unittest.TestCase):
 
     def testGetNestedSubTestDescriptionWithoutDocstring(self):
         with self.subTest(foo=1):
-            with self.subTest(bar=2):
+            with self.subTest(baz=2, bar=3):
                 result = unittest.TextTestResult(None, True, 1)
                 self.assertEqual(
                         result.getDescription(self._subtest),
                         'testGetNestedSubTestDescriptionWithoutDocstring '
-                        '(' + __name__ + '.Test_TestResult) (bar=2, foo=1)')
+                        '(' + __name__ + '.Test_TestResult) (baz=2, bar=3, foo=1)')
+
+    def testGetDuplicatedNestedSubTestDescriptionWithoutDocstring(self):
+        with self.subTest(foo=1, bar=2):
+            with self.subTest(baz=3, bar=4):
+                result = unittest.TextTestResult(None, True, 1)
+                self.assertEqual(
+                        result.getDescription(self._subtest),
+                        'testGetDuplicatedNestedSubTestDescriptionWithoutDocstring '
+                        '(' + __name__ + '.Test_TestResult) (baz=3, bar=4, foo=1)')
 
     @unittest.skipIf(sys.flags.optimize >= 2,
                      "Docstrings are omitted with -O2 and above")
@@ -362,7 +371,7 @@ class Test_TestResult(unittest.TestCase):
             self.assertEqual(
                 result.getDescription(self._subtest),
                ('testGetSubTestDescriptionWithOneLineDocstring '
-                '(' + __name__ + '.Test_TestResult) (bar=2, foo=1)\n'
+                '(' + __name__ + '.Test_TestResult) (foo=1, bar=2)\n'
                 'Tests getDescription() for a method with a docstring.'))
 
     @unittest.skipIf(sys.flags.optimize >= 2,
@@ -390,7 +399,7 @@ class Test_TestResult(unittest.TestCase):
             self.assertEqual(
                 result.getDescription(self._subtest),
                ('testGetSubTestDescriptionWithMultiLineDocstring '
-                '(' + __name__ + '.Test_TestResult) (bar=2, foo=1)\n'
+                '(' + __name__ + '.Test_TestResult) (foo=1, bar=2)\n'
                 'Tests getDescription() for a method with a longer '
                 'docstring.'))
 
index fc9e1dee6fc16cbeabca921395918434787b935a..f33589d0085a5c1852b9afb11d3c57add3f56f5e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -374,6 +374,9 @@ Extension Modules
 Library
 -------
 
+- bpo-30664: The description of a unittest subtest now preserves the order of
+  keyword arguments of TestCase.subTest().
+
 - [Security] bpo-30730: Prevent environment variables injection in subprocess on
   Windows.  Prevent passing other environment variables and command arguments.