Python 2断言Sequal不正确的结果
我在Python2下的Python 2断言Sequal不正确的结果,python,python-unittest,Python,Python Unittest,我在Python2下的unittest.TestCase.assertItemsEqual函数中遇到了一个有趣的情况;将我的发现发布在这里供子孙后代参考 以下单元测试在Python2下应该成功时中断: import unittest class Foo(object): def __init__(self, a=1, b=2): self.a = a self.b = b def __repr__(self): return '(
unittest.TestCase.assertItemsEqual
函数中遇到了一个有趣的情况;将我的发现发布在这里供子孙后代参考
以下单元测试在Python2下应该成功时中断:
import unittest
class Foo(object):
def __init__(self, a=1, b=2):
self.a = a
self.b = b
def __repr__(self):
return '({},{})'.format(self.a, self.b)
def __eq__(self, other):
return self.a == other.a and self.b == other.b
def __lt__(self, other):
return (self.a, self.b) < (other.a, other.b)
class Test(unittest.TestCase):
def test_foo_eq(self):
self.assertEqual(sorted([Foo()]), sorted([Foo()]))
self.assertItemsEqual([Foo()], [Foo()])
unittest.main()
这相当令人困惑,因为州政府:
它[assertItemsEqual
]相当于assertEqual(已排序(预期)、已排序(实际))
,但它也适用于不可损坏对象的序列
在Python3下通过了相同的测试(将self.assertItemsEqual
替换为self.assertCountEqual
,因为名称已更改)
编辑:在发布这个问题之后,我确实发现了另一个问题,它涵盖了既没有定义
\uuuuueq\uuuuu
也没有定义\uuuuuhash\uuuuuu
的情况。为了让测试在Python2和Python3下都通过,我必须在Foo
中添加一行\uuhash\uuuuu=None
assertItemsEqual
/assertCountEqual
函数根据每个列表中的项目是否可散列而采用不同的代码路径。并根据:
如果类没有定义\uuuu cmp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;如果它定义了\uu cmp\uu()
或\uu eq\uuu()
而不是\uuu hash\uuu()
,则其实例将无法在哈希集合中使用
考虑到这一点,定义了\uuuuuueq\uuuuu
时,Python 2和3在\uuuuuuuu散列
方面有不同的行为:
- 在Python2中,定义
\uuuuuueq\uuuu
不会影响提供的默认值\uuuuuuu散列
,但尝试在散列容器中使用该项会导致实现定义的行为(例如,键可能会被复制,因为它们具有不同的散列,即使\uuuuuueq\uuu
将返回True
)
- 在Python3中,定义
\uuuuuu eq\uuuu
将\uuuuu hash\uuuu
设置为None
从Python2.6开始,\uuu hash\uu
可以显式设置为None
,以使类不可破坏。在我的例子中,这是获得assertItemsEqual
所必需的,以使用正确的比较算法,该算法依赖于\uuuuuuuueq\uuuuu
,而不是\uuuuuuuhash\uuuuu
======================================================================
FAIL: test_foo_eq (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/tsanders/scripts/one_offs/test_unittest_assert_items_equal2.py", line 17, in test_foo_eq
self.assertItemsEqual([Foo()], [Foo()])
AssertionError: Element counts were not equal:
First has 1, Second has 0: (1,2)
First has 0, Second has 1: (1,2)
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)