I have been working on Learn Python the Hard Way 2nd Ed and it has been fantastic. My question has to do with Exercise 49 (http://learnpythonthehardway.org/book/ex49.html), which is about writing nose unit tests that covers code given in the book. I attempting to write a test that covers this function:
def parse_subject(word_list, subj):
verb = parse_verb(word_list)
obj = parse_object(word_list)
return Sentence(subj, verb, obj)
I tried to run this test:
from nose.tools import *
from ex48 import engine
def test_parse_subject():
word_list = [('verb', 'verb'),
('direction', 'direction')]
test_subj = ('noun', 'noun')
test_verb = ('verb', 'verb')
test_obj = ('d开发者_如何转开发irection', 'direction')
assert_equal(engine.parse_subject(word_list, ('noun', 'noun')),
engine.Sentence(test_subj, test_verb, test_obj))
But it returns with an error, as the two Sentence objects are not the EXACT same object:
⚡ nosetests
.....F..........
======================================================================
FAIL: tests.engine_tests.test_parse_subject
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.2/lib/python2.7/site-packages/nose/case.py", line 187, in runTest
self.test(*self.arg)
File "/Users/gregburek/code/LPTHW/projects/ex48/tests/engine_tests.py", line 59, in test_parse_subject
engine.Sentence(test_subj, test_verb, test_obj))
AssertionError: <ex48.engine.Sentence object at 0x101471390> != <ex48.engine.Sentence object at 0x1014713d0>
----------------------------------------------------------------------
Ran 16 tests in 0.018s
FAILED (failures=1)
How may I use nose to check that the two objects should be the same?
I'm kind of a noob working on the same exact exercise #49 right now and ran into the same error and have the same question you do. Since no one else answered, I thought I may as well throw in what I did which was simply breaking down the Sentence Object into it's three parts and making sure they're equivalent. It looks something like this:
def test_parse_subject():
word_list = [('verb','run'),
('noun','Bear'),
('verb','jump')]
subj = ('noun', 'me')
result = ex49.parse_subject(word_list,subj)
assert_equal(result.subject, 'me')
assert_equal(result.verb, 'run')
assert_equal(result.object, 'Bear')
I would love to know though if nose.tools has a function that allows you to directly compare object equivalency.
Same issue here. Not sure if this is any better than what Thomas did but instead of just comparing the values of the object, I created another object in the test giving it the exact values I expected.
I also used the built-in function vars() and imported pprint from the module pprint so I wouldn't have to compare each value individually.
from nose.tools import *
from pprint import pprint
from ex49 import sentence_parser
def test_parse_sentence():
# Test word list for parser to parse
word_list = [('verb', 'verb'), ('stop', 'stop'), ('noun', 'noun')]
# Here I create an object using the parse_sentence function
theSentence = sentence_parser.parse_sentence(word_list)
#Then I use assert_equal to compare the object created by the parse_sentence function to an object that I create by passing it the expected values.
assert_equal(pprint(theSentence),
pprint(sentence_parser.Sentence(('noun', 'player'),
('verb', 'verb'),
('noun', 'noun'))))
Alternatively, add below method to Sentence class and your original assert_equal should work. In other word, you are asserting if two objects are "equal". If you think two Sentence objects are equal to each other if values of all the instance variables are identical then below codes achieve what you want:
class Sentence(object):
...
# Python 2.X
def __cmp__(self, other):
return self.__dict__ == other.__dict__
# Python 3.X
def __eq__(self, other):
return self.__dict__ == other.__dict__
...
Hope this helps!
This cheat sheet by github user (bitsai) uses a different technique that you could also try out. Adding a method to Sentence class that converts the class attributes to a tuple. Worth a try. Am using it and it makes even more sense.
Click here.
You can also try:
class Sentence(object):
def __init__(self, subject, verb, obj):
self.subject = subject[1]
self.verb = verb[1]
self.object = obj[1]
def __eq__(self, other):
if type(other) is type(self):
return self.__dict__ == other.__dict__
else:
return False
精彩评论