So I was having an issue with unittest results failing due to the test claiming that an assertEqual statement was failing.
Error code:
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))}
Here's the unittest code below:
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
which is testing these classes:
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)
The prob object being created in the testing code is an instance of the Instance class, which, among other things, contains two dictionaries (after a method call), one for the nodes and one for the edges. The nodes are generated using the populated_instance method of the Generate class, and the edges are generated from the nodes by different method call within the populated_instance method.
The prob.edges dictionary looks like this:
{1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))}
and is made up of instances of the Node class contained within instances of the Edge class. As you can see in the unittest code above, I've created an equivalent dictionary using the same objects with the same values.
So, I knew for sure that the prob.edges dictionary and the comparison_edges dictionary were identical, were entirely made up of properly instantiated class objects, and that I wasn't comparing any of these objects to strings that looked like objects.
I found this SO question about a similar problem: Python unittest failure when results appear equal... however it shed no light on my issue.
After an hour or so I eventually realised what was happening, and it was a different problem entirely. So I'm going to post my question and the answer as well.