15

在为我的班级编写一些测试时,我遇到了有趣的简单问题。我想 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

4 回答 4

8

您可以尝试PyHamcrest (已纠正示例)

assert_that(obj.exportToDict(), has_entries(
                                    { 'state': 2347,
                                      'neighbours': contains_inanyorder(1,2,3) }))

(第一个值 2347 实际上被包装在一个隐式equal_to匹配器中。)

于 2013-01-24T02:36:26.160 回答
1

你可以做:

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)
于 2013-01-23T23:24:59.217 回答
0

如何使用all

assert all( (k,v) in resulting_dictionary.iteritems() 
            for (k,v) in obj.exportToDict().iteritems() )

我在 py.test 中使用了类似的东西,但我认为它应该适合你。


一位评论者指出,订单会在这里搞砸我——很公平……那么我只会使用套装。

于 2013-01-23T23:23:14.283 回答
0

也许您可以分别检查这两个元素:

obj_dict = obj.exportToDict()
self.assertEqual(resulting_dictionary['state'], obj_dict['state'])
self.assertCountEqual(resulting_dictionary['neighbours'], obj_dict['neighbours'])
于 2014-01-03T13:51:04.183 回答