Python unittest - утверждающий словарь со списками
При написании некоторых тестов для моего класса я столкнулся с интересной простой проблемой. Я хотел бы assertDictEqual два словаря, содержащие некоторый список. Но эти списки не могут быть отсортированы одинаково -> что приводит к провалу теста
Пример:
def test_myobject_export_into_dictionary(self):
obj = MyObject()
resulting_dictionary = {
'state': 2347,
'neighbours': [1,2,3]
}
self.assertDictEqual(resulting_dictionary, obj.exportToDict())
Время от времени происходит сбой, в зависимости от порядка элементов в списке
FAIL: test_myobject_export_into_dictionary
------------------------------------
- 'neighbours': [1,2,3],
+ 'neighbours': [1,3,2],
Есть идеи, как утверждать это простым способом?
Я думал об использовании set
вместо list
или сортировка списков перед сравнением.
4 ответа
Вы можете попробовать PyHamcrest (пример исправлен)
assert_that(obj.exportToDict(), has_entries(
{ 'state': 2347,
'neighbours': contains_inanyorder(1,2,3) }))
(Первое значение 2347 фактически оборачивается неявным equal_to
согласовани.)
Ты можешь сделать:
a = {i:sorted(j) if isinstance(j, list) else j for i,j in resulting_dictionary.iteritems()}
b = {i:sorted(j) if isinstance(j, list) else j for i,j in obj.exportToDict().iteritems()}
self.assertDictEqual(a, b)
Может быть, вы можете проверить два элемента отдельно:
obj_dict = obj.exportToDict()
self.assertEqual(resulting_dictionary['state'], obj_dict['state'])
self.assertCountEqual(resulting_dictionary['neighbours'], obj_dict['neighbours'])
Как насчет использования all
:
assert all( (k,v) in resulting_dictionary.iteritems()
for (k,v) in obj.exportToDict().iteritems() )
Я использую что-то подобное с py.test, но я думаю, что это должно работать для вас.
Комментатор указал, что ордер меня здесь напортачит - достаточно справедливо... Я бы тогда использовал наборы.