Trying to assert that two dictionaries that have nested contents are equal to each other (order doesn't matter) with pytest. What's the pythonic way to do this?
Asked
Active
Viewed 6.5k times
67
-
14Have you tried `assert d1 == d2`? Btw what is your nested content? – Szabolcs Nov 09 '17 at 12:07
6 Answers
67
pytest's magic is clever enough. By writing
assert {'a': {'b': 2, 'c': {'d': 4} } } == {'a': {'b': 2, 'c': {'d': 4} } }
you will have a nested test on equality.

Hawkeye Parker
- 7,817
- 7
- 44
- 47

linqu
- 11,320
- 8
- 55
- 67
-
4This should be the accepted answer. The desired functionality is already there automatically in pytest when you assert that two dictionaries are equal. There's no need either to write dedicated logic or to import anything from unittest. – monotasker Oct 15 '22 at 15:07
-
3It isn't even pytest. This is just using the regular Python equality operator. Only if the assertion fails does pytest's magic kick in to display the dicts and/or their differences. – Jonathan Hartley May 17 '23 at 20:13
56
Don't spend your time writing this logic yourself. Just use the functions provided by the default testing library unittest
from unittest import TestCase
TestCase().assertDictEqual(expected_dict, actual_dict)

Vincent Claes
- 3,960
- 3
- 44
- 62
-
2When dict is big, and we no see diff details, variant use with params maxDiff: test = TestCase() | test.maxDiff = None | test.assertEqual(expected_dict, actual_dict) – Dmytro Ivashchenko Sep 22 '22 at 07:48
9
I guess a simple assert equality test should be okay:
>>> d1 = {n: chr(n+65) for n in range(10)}
>>> d2 = {n: chr(n+65) for n in range(10)}
>>> d1 == d2
True
>>> l1 = [1, 2, 3]
>>> l2 = [1, 2, 3]
>>> d2[10] = l2
>>> d1[10] = l1
>>> d1 == d2
True
>>> class Example:
stub_prop = None
>>> e1 = Example()
>>> e2 = Example()
>>> e2.stub_prop = 10
>>> e1.stub_prop = 'a'
>>> d1[11] = e1
>>> d2[11] = e2
>>> d1 == d2
False

Szabolcs
- 3,990
- 18
- 38
6
General purpose way is to:
import json
# Make sure you sort any lists in the dictionary before dumping to a string
dictA_str = json.dumps(dictA, sort_keys=True)
dictB_str = json.dumps(dictB, sort_keys=True)
assert dictA_str == dictB_str

William
- 705
- 1
- 6
- 17
-
5works, but it's very tedious to find the difference between the two objects afterwards – linqu Jan 29 '21 at 20:53
0
assert all(v == actual_dict[k] for k,v expected_dict.items()) and len(expected_dict) == len(actual_dict)

Damel Lambert-Powell
- 97
- 3
-
5This is unnecessary. If two dicts are equal then necessarily their lengths will be the same, and so will be their elements. Barely `dict1==dict2` does the trick. Also to be rigurous, if item per item check was neccesary, you would need to go over the nested elements too. – Aug 23 '18 at 21:26
-
Said simple evaluation does exactly a multi-dimension-wise check, as opposed to the `is` operator, that solely checks for the memory pointer. – Aug 23 '18 at 21:29
-4
your question is not very specific but with what i can understand, you are either trying to check if the length are the same
a = [1,5,3,6,3,2,4]
b = [5,3,2,1,3,5,3]
if (len(a) == len(b)):
print True
else:
print false
or checking if the list values are the same
import collections
compare = lambda x, y: collections.Counter(x) == collections.Counter(y)
compare([1,2,3], [1,2,3,3])
print compare #answer would be false
compare([1,2,3], [1,2,3])
print compare #answer would be true
but for dictionaries you could also use
x = dict(a=1, b=2)
y = dict(a=2, b=2)
if(x == y):
print True
else:
print False

Adeojo Emmanuel IMM
- 2,104
- 1
- 19
- 28