Basically, it allows unittest to give you more information about why the test failed (“diagnostics”, to use the language from “Growing Object-Oriented Software Guided by Tests” by Steve Freeman and Nat Pryce). Compare these two tests:
import unittest
class DemoTest(unittest.TestCase):
D1 = {'a': 1, 'b': 2, 'c': [1, 2]}
D2 = {'a': 1, 'b': 2, 'c': [1]}
def test_not_so_useful(self):
self.assertTrue(self.D1 == self.D2)
def test_useful(self):
self.assertDictEqual(self.D1, self.D2)
if __name__ == "__main__":
unittest.main()
And their outputs:
======================================================================
FAIL: test_not_so_useful (__main__.DemoTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "path/to/file.py", line 10, in test_not_so_useful
self.assertTrue(self.D1 == self.D2)
AssertionError: False is not true
vs.
======================================================================
FAIL: test_useful (__main__.DemoTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "path/to/file.py", line 13, in test_useful
self.assertDictEqual(self.D1, self.D2)
AssertionError: {'a': 1, 'b': 2, 'c': [1, 2]} != {'a': 1, 'b': 2, 'c': [1]}
- {'a': 1, 'b': 2, 'c': [1, 2]}
? ---
+ {'a': 1, 'b': 2, 'c': [1]}
In the latter, you can see exactly what the difference was, you don’t have to work it out yourself. Note that you can just use the standard assertEqual instead of assertDictEqual, with the same result; per the docs
…it’s usually not necessary to invoke these methods directly.