Reputation: 75
Is it possible to use assert_equal to compare objects? I keep seeing this error:
AssertionError: <ex49.parser.Sentence object at 0x01F1BAF0> !=
<ex49.parser.Sentence object at 0x01F1BB10>
The relevant code fragment:
def test_parse_subject():
testsentence = "princess go east"
result = lexicon.scan(testsentence)
Sent = parse_sentence(result)
ResultSent = Sentence(('subject', 'princess'),
('verb', 'go'),
('object', 'east'))
print ResultSent.subject
print ResultSent.verb
print ResultSent.object
print Sent.subject
print Sent.verb
print Sent.object
assert_equal(Sent, ResultSent)
The print outputs on screen suggests that the objects have the same contents - yet the assertion error shows up. Why is this? Is there some way to use assert_equal to override this?
Upvotes: 2
Views: 2759
Reputation: 11
This is good info, For me, I was too lazy to search so I just compared the variables of the two objects as below:
def test_parse_subject():
word_list_a = lexicon.scan("eat the bear")
Sentence1 = Sentence(('noun','player'),('verb', 'eat'),('noun', 'bear'))
Sentence2 = parse_subject(word_list_a,('noun','player'))
assert_equal(Sentence2.subject, Sentence1.subject)
assert_equal(Sentence2.verb, Sentence1.verb)
assert_equal(Sentence2.object, Sentence1.object)
Upvotes: 1
Reputation: 932
I too am working through LPTHW ex49. Specifically for the context of this example, I was able to get it to work by adding the __eq__() method to the Sentence class, as follows:
Class Sentence(object):
def __init__(self, subject, verb, object_)
...
def __eq__(self, other):
return (self.subject == other.subject and
self.verb == other.verb and
self.object_ == other.object_)
Then, in the test file, I did:
# where LIST5 is defined above to give list of two tuples, [('verb', 'go'), ('direction', 'east')]
def test_parse_subject():
wordlist = list(LIST5)
sent = parse.Sentence(('noun', 'person'), ('verb'), ('go'), ('direction', 'east))
newsent = parse.parse_subject(wordlist, ('noun', 'person'))
assert_equal(newsent, sent)
As far as I can tell (new to this), assert_equal with nose and unittest will call the __eq__() method if it exists. In this case, the test is OK as long as the two objects have the same three values for subject, verb, object_. However, this took me a while to figure out, because I had a bug in my code, and the only thing nose would provide is the same error message that you received, even when I had the __eq__() method. That is, it provided "AssertionError: ...object at 0x... != ... object at 0x..." This misled me into thinking that the __eq__() method was not working, since it looked like it was comparing addresses. Not sure if there's a better way to do this.
NOTE: I renamed object to object_ because gedit was highlighting object as a python keyword. Not sure if this is recommended to use trailing underscore.
Upvotes: 0
Reputation: 846
I believe you need to implement the __eq__ method on the Sentence class.
assertEqual(first, second, msg=None)¶ Test that first and second are equal. If the values do not compare equal, the test will fail.
In addition, if first and second are the exact same type and one of list, tuple, dict, set, frozenset or unicode or any type that a subclass registers with addTypeEqualityFunc() the type-specific equality function will be called in order to generate a more useful default error message (see also the list of type-specific methods).
The correspondence between operator symbols and method names is as follows: xlt(y), x<=y calls x.le(y), x==y calls x.eq(y), x!=y and x<>y call x.ne(y), x>y calls x.gt(y), and x>=y calls x.ge(y).
Python data model documentation
An example:
import unittest
class A:
def __init__(self, num):
self.num = num
def __eq__(self, other):
return self.num == other.num
class Test(unittest.TestCase):
def test(self):
a1 = A(1)
a12 = A(1)
a2 = A(2)
self.assertEqual(a1, a1, 'a1 != a1')
self.assertEqual(a1, a12, 'a1 != a12')
self.assertEqual(a1, a2, 'a1 != a2')
def main():
unittest.TestRunner(Test())
if __name__ == '__main__':
unittest.main()
Now comment the __eq__ method and see the difference.
Upvotes: 6