【发布时间】:2015-04-17 13:10:44
【问题描述】:
Python 2.7 docs 声明assertItemsEqual“等同于assertEqual(sorted(expected), sorted(actual))”。在下面的示例中,除 test4 之外的所有测试都通过了。为什么assertItemsEqual 在这种情况下会失败?
根据最小惊讶原则,给定两个迭代,我希望成功的assertEqual 意味着成功的assertItemsEqual。
import unittest
class foo(object):
def __init__(self, a):
self.a = a
def __eq__(self, other):
return self.a == other.a
class test(unittest.TestCase):
def setUp(self):
self.list1 = [foo(1), foo(2)]
self.list2 = [foo(1), foo(2)]
def test1(self):
self.assertTrue(self.list1 == self.list2)
def test2(self):
self.assertEqual(self.list1, self.list2)
def test3(self):
self.assertEqual(sorted(self.list1), sorted(self.list2))
def test4(self):
self.assertItemsEqual(self.list1, self.list2)
if __name__=='__main__':
unittest.main()
这是我机器上的输出:
FAIL: test4 (__main__.test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "assert_test.py", line 25, in test4
self.assertItemsEqual(self.list1, self.list2)
AssertionError: Element counts were not equal:
First has 1, Second has 0: <__main__.foo object at 0x7f67b3ce2590>
First has 1, Second has 0: <__main__.foo object at 0x7f67b3ce25d0>
First has 0, Second has 1: <__main__.foo object at 0x7f67b3ce2610>
First has 0, Second has 1: <__main__.foo object at 0x7f67b3ce2650>
----------------------------------------------------------------------
Ran 4 tests in 0.001s
FAILED (failures=1)
【问题讨论】:
-
因为您还没有为
foo对象定义排序? -
谢谢。就您而言,如果我在
foo上定义 hash 方法,test4 通过。但是,文档声明 assertItemsEqual 适用于不可散列的对象。我误解了文档吗? -
我不太了解 Python,但错误消息清楚地告诉您,它通过计算两者中的唯一对象来比较列表,然后逐个键比较计数。比较是按对象地址进行的。由于每个列表中有不同的对象实例,因此列表比较不相等。如果你说
a = foo(1); b = foo(2); self.list1 = [a, b] self.list2 = [b, a],我敢打赌最后一次测试会通过。 -
它适用于基于对象地址的不可散列对象(地址总是允许散列)!
-
谢谢,吉恩。是的,测试将通过您修改后的示例。我的问题的重点是文档似乎不清楚(至少对我而言)——它们似乎暗示 assertEqual(sorted(actual), sorted(expected)) 等同于 assertItemsEqual(actual, expected),即使对于不可散列对象。