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 TestCase s 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))

(Mixin above is in the public domain.)

Further reading: How to override comparison operators in Python