diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 4a13f0a6751..a8b2f4d3f43 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -12,7 +12,6 @@ from .util import (strclass, safe_repr, sorted_list_difference, unorderable_list_difference) __unittest = True -TRUNCATED_DIFF = '\n[diff truncated...]' class SkipTest(Exception): """ @@ -169,6 +168,11 @@ class TestCase(object): longMessage = False + # This attribute sets the maximum length of a diff in failure messsages + # by assert methods using difflib. It is looked up as an instance attribute + # so can be configured by individual tests if required. + maxDiff = 80*8 + # Attribute used by TestSuite for classSetUp _classSetupFailed = False @@ -599,8 +603,7 @@ class TestCase(object): failUnlessRaises = _deprecate(assertRaises) failIf = _deprecate(assertFalse) - def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None, - max_diff=80*8): + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): """An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one @@ -613,7 +616,6 @@ class TestCase(object): datatype should be enforced. msg: Optional message to use on failure instead of a list of differences. - max_diff: Maximum size off the diff, larger diffs are not shown """ if seq_type != None: seq_type_name = seq_type.__name__ @@ -700,13 +702,17 @@ class TestCase(object): diffMsg = '\n' + '\n'.join( difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) - if max_diff is None or len(diffMsg) <= max_diff: - standardMsg += diffMsg - else: - standardMsg += diffMsg[:max_diff] + TRUNCATED_DIFF + + standardMsg = self._truncateMessage(standardMsg, diffMsg) msg = self._formatMessage(msg, standardMsg) self.fail(msg) + def _truncateMessage(self, message, diff): + max_diff = self.maxDiff + if max_diff is None or len(diff) <= max_diff: + return message + diff + return message + def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. @@ -805,9 +811,10 @@ class TestCase(object): self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: - standardMsg = ('\n' + '\n'.join(difflib.ndiff( + diff = ('\n' + '\n'.join(difflib.ndiff( pprint.pformat(d1).splitlines(), pprint.pformat(d2).splitlines()))) + standardMsg = self._truncateMessage('', diff) self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): @@ -924,8 +931,9 @@ class TestCase(object): 'Second argument is not a string')) if first != second: - standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), + diff = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + standardMsg = self._truncateMessage('', diff) self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index 14a386a6f39..7de79310ed4 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -592,20 +592,38 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing): self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) def testAssertSequenceEqualMaxDiff(self): + self.assertEqual(self.maxDiff, 80*8) seq1 = 'a' + 'x' * 80**2 seq2 = 'b' + 'x' * 80**2 diff = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), pprint.pformat(seq2).splitlines())) + + self.maxDiff = len(diff)//2 try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)//2) - except AssertionError as e: + + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) < len(diff)) + self.maxDiff = len(diff) * 2 try: - self.assertSequenceEqual(seq1, seq2, max_diff=len(diff)*2) - except AssertionError as e: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') + self.assertTrue(len(msg) > len(diff)) + + self.maxDiff = None + try: + self.assertSequenceEqual(seq1, seq2) + except self.failureException as e: + msg = e.args[0] + else: + self.fail('assertSequenceEqual did not fail.') self.assertTrue(len(msg) > len(diff)) def testAssertItemsEqual(self):