因此,我对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字典是完全相同的,完全由正确实例化的类对象组成,并且我没有将任何这些对象与看起来像对象的字符串进行比较。
我发现了类似的问题:Python unittest failure when results appear equal.然而,它并没有说明我的问题。
一个多小时后,我终于意识到发生了什么,这是一个完全不同的问题。所以我也要发布我的问题和答案。
发布于 2018-08-17 15:01:11
在我的例子中,答案是我没有在我的__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)测试第一和第二是相等的。如果值不相等,则测试将失败。 此外,如果第一和第二种类型与列表、元组、迪克、set、frozenset或unicode的类型完全相同,或者子类使用addTypeEqualityFunc()注册的任何类型,则将调用类型特定的相等函数,以生成更有用的默认错误消息(还请参见特定类型方法的列表)。 在2.7版本中更改:添加了类型特定的相等函数的自动调用。
在我看来,对自定义类调用的是“特定于类型的等式函数”,因此,如果不存在自定义__eq__()方法,则检查将失败。
详情请参阅下面@Humbalan的答案:)
发布于 2018-08-17 15:16:37
如果没有自己的__eq__()方法,Python只会比较对象的ID,当然它们并不相等。如果要测试不同对象属性的相等性,则需要__eq__()方法。事实上,你可以用这种方法来比较你想要的任何东西。我有一个例子,其中平等被定义为五个属性中的两个相等。其余三个属性没有得到考虑。
顺便提一下:在您的__eq__()方法中,您也应该检查对象类型的相等性。想象两个不同类的实例,它们具有相同的属性.
https://stackoverflow.com/questions/51898138
复制相似问题