由于测试声称unittest
语句失败,因此我遇到assertEqual
结果失败的问题。
错误代码:
AssertionError: {1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))} != {1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))}
这是下面的单元测试代码:
class InstanceTestCase(unittest.TestCase):
def setUp(self):
self.prob = Generate.populated_instance(3, 12345678)
node_one = Node(51, 98)
node_two = Node(31, 4)
node_three = Node(49, 80)
edge_one = Edge(node_one, node_two)
edge_two = Edge(node_one, node_three)
edge_three = Edge(node_two, node_three)
self.comparison_edges = {1: edge_one, 2: edge_two, 3: edge_three}
def test_Instance(self):
self.assertEqual(self.prob.edges, self.compare_edges_dict) # returning an error
正在测试这些类:
class Node:
"""Represents the nodes as points with a position x, y."""
def __init__(self, x=0, y=0):
"""Create a new node at x, y."""
self.x = x
self.y = y
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
def __repr__(self):
return str(self)
def __eq__(self, other):
if type(self) == type(other):
return self.x == other.x and self.y == other.y
else:
raise TypeError
def __hash__(self):
return hash((self.x, self.y))
class Edge:
"""Represents the edges as having a length and being bounded by two points."""
def __init__(self, node_one, node_two):
"""Create an edge using two nodes."""
self.node_one = node_one
self.node_two = node_two
def __str__(self):
return "({0}, {1})".format(self.node_one, self.node_two)
def __repr__(self):
return str(self)
class Instance:
count = 0
def __init__(self, node_count=0, seed=0, nodes=None, edges=None, solution_path=None, solve_time=0):
"""Create a new problem with x number of nodes.
Leave seed blank for random seed, otherwise put an eight digit number to use for the seed."""
self.node_count = node_count
self.seed = seed
self.nodes = nodes
self.edges = edges
self.solution_path = solution_path
self.solve_time = solve_time
Instance.count += 1
# makes outputs from print easier to read
def __str__(self):
return "ID: {0}\n" \
"Node count: {1}\n" \
"Seed: {2}\n" \
"Nodes: {3}\n" \
"Edges: {4}\n" \
"Solve time: {5}".format(self.problem_id,
self.node_count,
self.seed,
self.nodes,
self.edges,
self.solve_time)
def __repr__(self):
return str(self)
在测试代码中创建的prob
对象是Instance
类的实例,其中除其他外,包含两个字典(在方法调用之后),一个字典用于节点,一个字典用于节点。对于边缘。使用populated_instance
类的Generate
方法生成节点,并通过populated_instance
方法内的不同方法调用从节点生成边缘。
prob.edges词典如下:
{1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))}
并且由Node
类的实例中包含的Edge
类的实例组成。如您在上面的单元测试代码中所看到的,我已经使用具有相同值的相同对象创建了一个等效字典。
因此,我确定prob.edges
字典和comparison_edges
字典是相同的,完全由正确实例化的类对象组成,并且我没有将这些对象与看起来像对象的字符串。
我找到了一个类似问题的SO问题: Python unittest failure when results appear equal ...但是对我的问题没有任何启示。
一个小时后,我终于意识到发生了什么,这完全是另一个问题。所以我也要发布我的问题和答案。
答案 0 :(得分:2)
没有自己的__eq__()
方法,Python仅比较对象的ID,它们当然是不相等的。如果要测试不同对象的属性是否相等,则需要__eq__()
方法。实际上,您可以使用此方法进行比较。我有一个示例,其中平等定义为五个属性中的两个相等。未考虑其余三个属性。
顺便说一句:在您的__eq__()
方法中,您还应该检查对象类型的相等性。想象一下不同类别的两个实例,它们随机具有相同的属性...
答案 1 :(得分:1)
对于我来说,答案是我没有在__eq__()
类中实现Edge
方法。
此方法将由其他一些方法自动调用,如果您的类中未实现该方法,则需要进行相等性检查的方法可能无法正常工作。
我的Edge
类最初看起来像这样:
class Edge:
"""Represents the edges as having a length and being bounded by two points."""
def __init__(self, node_one, node_two):
"""Create an edge using two nodes."""
self.node_one = node_one
self.node_two = node_two
def __str__(self):
return "({0}, {1})".format(self.node_one, self.node_two)
def __repr__(self):
return str(self)
并包括此内容之后...
def __eq__(self, other):
if type(self) == type(other):
return self.node_one == other.node_one and self.node_two == other.node_two
else:
raise TypeError
在assertEqual
中使用的相等性检查效果很好。
(注意:我已经在我的__eq__()
类中实现了覆盖的Node
方法,并且测试确认删除该方法也破坏了上面的检查。)
从python文档(https://docs.python.org/2/library/unittest.html)看这件事:
assertEqual(first, second, msg=None)
测试第一个和第二个是 等于。如果值不相等,则测试将失败。此外,如果first和second是完全相同的类型,并且 列表,元组,字典,集合,frozenset或unicode或 子类向
addTypeEqualityFunc()
注册特定类型 相等函数将被调用以生成更有用的 默认错误消息(另请参见类型特定方法的列表)。在2.7版中进行了更改:添加了针对特定类型的自动调用 相等函数。
在我看来,自定义类上正在调用“特定于类型的相等函数”,因此,如果自定义__eq__()
方法不存在,则检查将失败。
有关更多详细信息,请参见下面@Humbalan的回答:)