Search code examples
pythonpytest

Check if two objects have equal content in Pytest


I'm learning how to use Pytest (and unit testing in general) and I would like to write a test to check if two objects of the same class have identical attributes.

Example:

class Something(object):
    def __init__(self, a, b):
        self.a, self.b = a, b

    def __repr__(self):
        return 'Something(a={}, b={})'.format(self.a, self.b)

def test_equality():
    obj1 = Something(1, 2)
    obj2 = Something(1, 2)
    assert obj1.a == obj2.a
    assert obj1 == obj2

This test fails with AssertionError on third assert:

    def test_equality():
        obj1 = Something(1, 2)
        obj2 = Something(1, 2)
        assert obj1.a == obj2.a
        assert obj1.b == obj2.b                                                                                                                                                                                                               
>       assert obj1 == obj2                                                                                                                                                                                                                   
E       assert Something(a=1, b=2) == Something(a=1, b=2)                                                                                                                                                                                     

tests/test_model.py:13: AssertionError

It is possible in Python or Pytest to use just assert obj1 == obj2? Should I implement "rich comparison" methods for each class I would like to test that way or there is some simpler way?


Solution

  • Override the _eq_ function of Something.

    def __eq__(self, other):
        if isinstance(self, other.__class__):
            return self.a == other.a and self.b == other.b
        return False
    

    Also.

    assert obj1 == obj2
    

    is actually a two-part statement. first is the expression obj1 == obj2, which calls obj1._eq_(obj2) and returns a boolean, the second asserts that boolean for truth.