使用
pytest
时,当两个对象不等价时,我会得到漂亮漂亮的打印:
Expected :Foo(id='red', other_thing='green')
Actual :Foo(id='red', other_thing='blue')
<Click to see difference>
def test_baz():
oneFoo = Foo(id="red", other_thing="blue")
twoFoo = Foo(id="red", other_thing="green")
> assert oneFoo == twoFoo
E AssertionError: assert Foo(id='red', other_thing='blue') == Foo(id='red', other_thing='green')
E
E Full diff:
E - Foo(id='red', other_thing='green')
E ? ^^ --
E + Foo(id='red', other_thing='blue')
E ? ^^^
baz.py:22: AssertionError
如果我直接在代码中使用断言,我只会得到一个
AssertionError
和一个堆栈跟踪。
我现在正在编写一些集成测试,这些测试不是由 pytest 驱动的,但希望在两个项目(特别是 Pydantic 数据类)不相等时进行漂亮的打印。
平等应该使用
__eq__
来实现:
例如:
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if isinstance(other, Foo):
return self.x == other.x and self.y == other.y
return False
def __hash__(self):
return hash((self.x, self.y))
a = Foo(1, 2)
b = Foo(1, 2)
c = Foo(3, 4)
print(a == b)
print(a == c)
my_dict = {a: 'value 1', c: 'value 3'}
print(my_dict[a])
True
False
value 1
hash()
。但实施这一点是一个很好的做法。
def __hash__(self):
return hash((self.x, self.y))
实际上,在您的代码中,这些对象并不相等,因此出现
AssertionError
。如果您想用任何东西、您自己的自定义错误或其他任何东西重写它,那么您必须将其添加到您的 eq 方法中。
class Foo:
def __init__(self, id, other_thing):
self.id = id
self.other_thing = other_thing
def __eq__(self, other):
if isinstance(other, Foo):
return self.id == other.id and self.other_thing == other.other_thing
return False
def test_baz():
oneFoo = Foo(id="red", other_thing="blue")
twoFoo = Foo(id="red", other_thing="green")
try:
assert oneFoo == twoFoo
except AssertionError:
raise ValueError(f"{oneFoo.__dict__} and {twoFoo.__dict__} are not equal.")
test_baz()
raise ValueError(f"{oneFoo.__dict__} and {twoFoo.__dict__} are not equal.")
ValueError: {'id': 'red', 'other_thing': 'blue'} and {'id': 'red', 'other_thing': 'green'} are not equal.