Skip to content

Instantly share code, notes, and snippets.

@adamghill
Created December 2, 2023 20:51
Show Gist options
  • Save adamghill/94989c1ecde233c11ac44dba5d36050b to your computer and use it in GitHub Desktop.
Save adamghill/94989c1ecde233c11ac44dba5d36050b to your computer and use it in GitHub Desktop.
Helper method to verify two dictionaries are the same with helpful error messages
from typing import Union
def assert_dictionaries(dictionary_one: Union[dict, list], dictionary_two: dict) -> None:
"""Helper method to verify two dictionaries are the same. Display helpful error messages
when the two dictionaries are different.
Args:
dictionary_one: The first dictionary.
dictionary_two: The second dictionary.
"""
if isinstance(dictionary_one, dict):
dictionary_one_key_intersection = set(dictionary_one.keys()) - set(dictionary_two.keys())
missing_keys = ", ".join(dictionary_one_key_intersection)
assert not dictionary_one_key_intersection, f"Missing {missing_keys!r} keys from {dictionary_two!r}"
dictionary_two_key_intersection = set(dictionary_two.keys()) - set(dictionary_one.keys())
additional_keys = ", ".join(dictionary_two_key_intersection)
assert not dictionary_two_key_intersection, f"Unknown {additional_keys!r} keys in {dictionary_one!r}"
for key, val in dictionary_one.items():
assert dictionary_two[key] == val, f"{dictionary_two[key]!r} not equal to {val!r}"
elif isinstance(dictionary_one, (list, set, tuple)):
for item in dictionary_one:
return assert_dictionaries(item, dictionary_two)
else:
raise Exception(f"Unknown type of {dictionary_one}: type(dictionary_one)")
import pytest
from tests.helpers import assert_dictionaries
def test_assert_dictionaries():
assert_dictionaries({}, {})
def test_assert_dictionaries_with_dicts():
assert_dictionaries({"test-key": "test-value"}, {"test-key": "test-value"})
def test_assert_dictionaries_with_lists():
assert_dictionaries({"test-key": ["test-value"]}, {"test-key": ["test-value"]})
def test_assert_dictionaries_with_lists_of_dicts():
assert_dictionaries(
{"test-key": [{"test-value-1": "test-value-1"}]}, {"test-key": [{"test-value-1": "test-value-1"}]}
)
def test_assert_dictionaries_missing_key():
expected = "AssertionError: Missing 'test-key' keys from {}"
with pytest.raises(AssertionError) as e:
assert_dictionaries({"test-key": "test-value"}, {})
actual = e.exconly()
assert expected == actual
def test_assert_dictionaries_missing_multiple_keys():
expected = (
"AssertionError: Missing 'test-key-1, test-key-2' keys from {}",
"AssertionError: Missing 'test-key-2, test-key-1' keys from {}",
)
with pytest.raises(AssertionError) as e:
assert_dictionaries({"test-key-1": "test-value-1", "test-key-2": "test-value-2"}, {})
actual = e.exconly()
assert actual in expected
def test_assert_dictionaries_unknown_key():
expected = "AssertionError: Unknown 'test-key' keys in {}"
with pytest.raises(AssertionError) as e:
assert_dictionaries({}, {"test-key": "test-value"})
actual = e.exconly()
assert expected == actual
def test_assert_dictionaries_missing_list():
expected = "AssertionError: '' not equal to [{'test-value'}]"
with pytest.raises(AssertionError) as e:
assert_dictionaries({"test-list": [{"test-value"}]}, {"test-list": ""})
actual = e.exconly()
assert expected == actual
def test_assert_dictionaries_list_missing_dict():
expected = "AssertionError: [] not equal to [{'test-value'}]"
with pytest.raises(AssertionError) as e:
assert_dictionaries({"test-list": [{"test-value"}]}, {"test-list": []})
actual = e.exconly()
assert expected == actual
def test_assert_dictionaries_list_dict_missing_key():
expected = "AssertionError: [{}] not equal to [{'test-value'}]"
with pytest.raises(AssertionError) as e:
assert_dictionaries({"test-list": [{"test-value"}]}, {"test-list": [{}]})
actual = e.exconly()
assert expected == actual
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment