How to test your __eq__ / __ne__ / __cmp__
In Python, a common mistake is to implement __eq__ on your object without also implementing __ne__. Even worse, your unit tests will often hide the error because the default object-identity __ne__ will probably satisfy your assertions.
If you’ve implemented __eq__ and __ne__, you might still have a mistake if the superclass has a __cmp__: Python’s cmp will fall back to the superclass’ __cmp__ instead of using your __eq__ (example). You’ll probably never notice this problem unless you use cmp(...) on your object.
When I need to exercise all possible combinations of ==, !=, and cmp, I mix this into my TestCases and use self.assertReally(Not)Equal(a, b):
class ReallyEqualMixin(object): def assertReallyEqual(self, a, b): # assertEqual first, because it will have a good message if the # assertion fails. self.assertEqual(a, b) self.assertEqual(b, a) self.assertTrue(a == b) self.assertTrue(b == a) self.assertFalse(a != b) self.assertFalse(b != a) self.assertEqual(0, cmp(a, b)) self.assertEqual(0, cmp(b, a)) def assertReallyNotEqual(self, a, b): # assertNotEqual first, because it will have a good message if the # assertion fails. self.assertNotEqual(a, b) self.assertNotEqual(b, a) self.assertFalse(a == b) self.assertFalse(b == a) self.assertTrue(a != b) self.assertTrue(b != a) self.assertNotEqual(0, cmp(a, b)) self.assertNotEqual(0, cmp(b, a))
No © on the above, enjoy.
Further reading: How to override comparison operators in Python
By Jeff on Nov 2nd, 2010 at 01:47
Thanks for putting this out there.
By uh on Nov 2nd, 2010 at 13:18
If you dont know how to test __eq__, __ne__, or __cmp__, you probably shouldn’t be using it in your code
By ivank on Nov 2nd, 2010 at 20:39
Right, but half of my point was to gently remind people that
__ne__and__cmp__exist. There’s a lot of buggy code out there already.