How to prevent truncating of string in unit test python

python unittest environment variables
python unittest parameterized
python unittest testsuite example
python unittest print
python unittest logging
pytest assert string contains
python unittest report
what is the parent class from which a test class has to be derived for running it with unittest?

I am doing a unit test in python for my program and I would like to do an assertEquals test.

My code looks something like this:

class UnitTest(unittest.TestCase):
      def test_parser(self):
          self.assertEquals(parser,"some long string", "String is not equal")

However, as my string is too long, i got something like testing[471 chars]0 != testing[473 chars]. I wanna see what is the exact difference between both the strings instead of seeing the truncated ones.

Anyone has an idea how to counter this problem ?

So, I landed on this question because I had an issue where I was using assertEqual() and 'self.maxDiff = None' wouldn't cause the full output to be displayed. Tracing through, it turned out that because the types of the two objects were different (one was a list, one was a generator), the code path that would make use of 'self.maxDiff' wasn't used. So, if you run into the issue where you need the full diff and 'self.maxDiff' isn't working, ensure the types of your two compared objects are the same.

Issue 21820: unittest: unhelpful truncating of long strings., unittest: unhelpful truncating of long strings. Type: behavior, Stage: Components: Tests, Versions: Python 3.9, Python 3.8, Python 3.7  I'm against the "don't trigger on non-strings", because the repr of non-strings can be pretty large. msg221398 - Author: Chris Withers (cjw296) * Date: 2014-06-24 06:36; No, it would not be enough. Please see the report above, the repr of non-strings may be large, but it's often intended that way and all of the string should be displayed.

unittest.TestCase.assertEquals tries to give you the actual difference in the string while at the same time making the text fit in your screen.

To do this it truncates the common sections, so sections that have no differences are truncated by replacing them with [<count> chars] chunks:

>>> case.assertEqual('foo' * 200, 'foo' * 100 + 'bar' + 'foo' * 99)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 821, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1194, in assertMultiLineEqual
    self.fail(self._formatMessage(msg, standardMsg))
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 666, in fail
    raise self.failureException(msg)
AssertionError: 'foof[291 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo[255 chars]ofoo' != 'foof[291 chars]oofoobarfoofoofoofoofoofoofoofoofoofoofoofoofo[255 chars]ofoo'
Diff is 1819 characters long. Set self.maxDiff to None to see it.

In the above example, the two strings share a long prefix, which has been shortened by replacing 291 characters with [291 chars] in both prefixes. They also share a long postfix, again shortened in both locations by replacing text with [255 chars].

The actual difference is still being displayed, right in the middle.

Of course, when you make that difference too long, then even the difference is truncated:

>>> case.assertEqual('foo' * 200, 'foo' * 80 + 'bar' * 30 + 'foo' * 80)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 821, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1194, in assertMultiLineEqual
    self.fail(self._formatMessage(msg, standardMsg))
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 666, in fail
    raise self.failureException(msg)
AssertionError: 'foof[231 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo[315 chars]ofoo' != 'foof[231 chars]oofoobarbarbarbarbarbarbarbarbarbarbarbarbarba[285 chars]ofoo'
Diff is 1873 characters long. Set self.maxDiff to None to see it.

Here, the common postfix is starting to differ, but the start of the difference is still visible, and should help you figure out where the text went wrong.

If this is still not enough, you can either increase or eliminate the diff limits. Set the TestCase.maxDiff attribute to a higher number (the default is 8 * 80, 80 lines of text), or set it to None to eliminate altogether:

self.maxDiff = None

Note that unless your string contains newlines that the diff is likely to be unreadable:

AssertionError: 'foof[231 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo[315 chars]ofoo' != 'foof[231 chars]oofoobarbarbarbarbarbarbarbarbarbarbarbarbarba[285 chars]ofoo' - foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoobarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarfoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo ? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In that case it may be more useful to wrap your input and output texts:

from textwrap import wrap

self.maxDiff = None
self.assertEquals(wrap(parser), wrap("some long string"), "String is not equal")

just so you get better and more readable diff output:

>>> from textwrap import wrap
>>> case.assertEqual(wrap('foo' * 200), wrap('foo' * 80 + 'bar' * 30 + 'foo' * 80))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 821, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1019, in assertListEqual
    self.assertSequenceEqual(list1, list2, msg, seq_type=list)
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 1001, in assertSequenceEqual
    self.fail(msg)
  File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/unittest/case.py", line 666, in fail
    raise self.failureException(msg)
AssertionError: Lists differ: ['foo[244 chars]oofoofoofoofoofoofoofoofoofoofoofoofoofoofoof'[336 chars]foo'] != ['foo[244 chars]oofoobarbarbarbarbarbarbarbarbarbarbarbarbarb'[306 chars]foo']

First differing element 3:
'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof'
'foofoofoofoofoofoofoofoofoofoobarbarbarbarbarbarbarbarbarbarbarbarbarb'

  ['foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof',
   'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo',
   'ofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo',
-  'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof',
-  'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo',
+  'foofoofoofoofoofoofoofoofoofoobarbarbarbarbarbarbarbarbarbarbarbarbarb',
+  'arbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarbarfoofoofoofoofoofoofo',
   'ofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo',
   'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoof',
   'oofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofo',
-  'ofoofoofoofoofoofoofoofoofoofoofoofoofoo']
+  'ofoofoofoo']

26.3. unittest — Unit testing framework, Here is a short script to test three string methods: The final block shows a simple way to run the tests. unittest.main() provides a command-line difference, rounding to the given number of decimal places (default 7), and comparing to zero. If you want to remove a certain number of characters from the right, use rstrip(). Alternatively, you can return a list of "words" contained in a string separated by a given character using split(), then keep the ones you want. Your best bet is to Google "python string operations".

To replace [... chars] and [truncated]... with actual characters (no matter how long, and no matter what the type of the compared values are), add this to your *_test.py file:

if 'unittest.util' in __import__('sys').modules:
    # Show full diff in self.assertEqual.
    __import__('sys').modules['unittest.util']._MAX_LENGTH = 999999999

Indeed, as other answers have noted, setting self.maxDiff = None doesn't help, it doesn't make the [... chars] disappear. However, this setting helps showing other types of long diffs, so my recommendation is doing both.

25.3. unittest — Unit testing framework, Here is a short script to test three string methods: The final block shows a simple way to run the tests. unittest.main() provides a command-line difference, rounding to the given number of decimal places (default 7), and comparing to zero. The unittest unit testing framework was originally inspired by JUnit and has a similar flavor as major unit testing frameworks in other languages. It supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework.

Issue 18996: unittest: more helpful truncating long strings, Error message in assertEqual() is not vary useful when compared long strings with long common prefix. It looks as: 'For the first time in his life h  Hence, in this Python Unittest tutorial, we discussed Unit Testing with Python. Moreover, we saw Python Unittest example and working. Also, we discussed Python Unit Testing frameworks and test case example with Python Unittest assert. We hope you can run your own tests for your code.

25.3. unittest — Unit testing framework, The final block shows a simple way to run the tests. unittest.main() provides a Like assertRaises() but also tests that regexp matches on the string rounding to the given number of decimal places (default 7), and comparing to zero. Note that​  Unit Testing is the first level of software testing where the smallest testable parts of a software are tested. This is used to validate that each unit of the software performs as designed. The unittest test framework is python’s xUnit style framework.

25.3. unittest — Unit testing framework, The unittest module provides classes that make it easy to support these The final block shows a simple way to run the tests. unittest.main() provides a rounding to the given number of decimal places (default 7), and comparing to zero. A list containing 2-tuples of TestCase instances and strings holding formatted  Truncation example. Here we have a string with three words in it. We first want to truncate the string to three characters. We use "0:3" to do this. Program: We truncate the string to 3 and to 7 characters. If we use an out of range number like 100 the entire string is returned.

Comments
  • You mean that the assertEquals output doesn't show you the full output?
  • yeah it does not show me the full output. Instead i see something like [471 chars] and [473 chars] respectively.
  • Have you tried setting self.maxDiff to a higher value or to None? The assertion message does tell you this.
  • I tried setting the maxDiff to None but I still receive the same output.
  • Where did you set that? In the test function itself? On the testcase as a class attribute?
  • To make this even more pernicious, the diff rendering might make it look like they are the same type, when they are not. When testing serializers you get and OrderedDict instead of dict, so comparing these two self.maxDiff has no effect. You have to do self.assertEqual(dict(result),expected_result))
  • This doesn't attempt to answer the original question: how to get the full dump of two strings (without shortening) if they are different.
  • The proposed solution (wrap(...)) works only for strings; it raises an exception if self.assertEqual is called on non-string types (whose repr is long). See my answer for a solution which works on all types.