I ran into an interesting situation with the unittest.TestCase.assertItemsEqual
function under Python 2; posting my findings here for posterity.
The following unit test breaks under Python 2 when it should succeed:
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()
Here is the output:
======================================================================
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)
This is pretty confusing since the docs state:
It [
assertItemsEqual
] is the equivalent ofassertEqual(sorted(expected), sorted(actual))
but it works with sequences of unhashable objects as well.
The same test passes under Python 3 (after swapping self.assertItemsEqual
for self.assertCountEqual
, since the name has changed).
EDIT: After posting this question, I did find this other question that covers the situation where neither __eq__
nor __hash__
is defined.