好的,问题是:在Zed Shaw的“学习Python困难之路”的exercise 49中,我们需要使用assert_raises()
测试几个例外。这是我正在测试的函数,如果省略assert_raises()
部分,它会通过测试:
def parse_verb(word_list):
skip(word_list, 'stop')
if peek(word_list) == 'verb':
return match(word_list, 'verb')
else:
raise ParserError("Expected a verb next.")
这是测试功能和臭名昭着的assert_raises()
行:
def parse_verb_test():
vrb_list = [('of', 'stop'), ('from', 'stop'), ('go', 'verb'), ('north', 'direction')]
assert_equal(parse_verb(vrb_list), ('go', 'verb'))
assert_equal(vrb_list, [('north', 'direction')])
assert_raises(ParserError, parse_verb, vrb_list)
它给了我以下输出:
.........E...
======================================================================
ERROR: tests.parser_tests.parse_verb_test
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/vsevolod/Repositories/ex48/tests/parser_tests.py", line 20, in parse_verb_test
assert_raises(ParserError, parse_verb, vrb_list)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 471, in assertRaises
callableObj(*args, **kwargs)
File "/Users/vsevolod/Repositories/ex48/ex48/parser.py", line 40, in parse_verb
raise ParserError("Expected a verb next.")
TypeError: object.__new__() takes no parameters
----------------------------------------------------------------------
Ran 13 tests in 0.042s
FAILED (errors=1)
我还试图摆脱assert_raises()
行并在函数前使用@raises(ParserError)
。它也没有完全奏效并产生相同的输出。
创建这样的单独测试有助于摆脱错误:
def parse_verb_fail():
fail_list = [('north', 'direction'), ('go', 'verb')]
assert_raises(ParserError, parse_verb, fail_list)
但现在测试被忽略了。
我做错了什么?
答案 0 :(得分:5)
我相信你的问题是ParserError
没有一个带字符串的构造函数(或ParserError
没有从Exception
扩展并尝试将字符串传递给基础对象的init方法......)。因此,当您尝试创建ParserError
时,您将获得TypeError
而不是ParserError
。由于您的assert_raises()
没有预料到TypeError
,因此无法捕捉到它。
编辑:
查看您链接到并播放的示例代码。你确定你有......
class ParserError(Exception): pass
......而不是......
class ParserError(object): pass
答案 1 :(得分:0)
Zed Shaw的“学习Python困难之路”仍然是一个很好的资源,所以也许我的贡献会有所帮助。
忽略parse_verb_fail函数的原因是,鼻子测试函数的名称必须带有“ test_”,或者如documentation更完整地说明:
默认情况下,任何与已配置的testMatch正则表达式((?:^ | [\ b _ \ .-])[Tt] est相匹配的函数或类-即在单词边界或在-之后具有test或Test或_),并且位于与该表达式匹配的模块中,该模块将作为测试运行。
这是我有效的解决方案:
def test_parse_errors():
subject_fail_list = [('stop', 'the'), ('direction', 'north')]
assert_raises(parser.ParseError, parser.parse_subject, subject_fail_list)
nose将运行此测试,并且将通过。将其中一个元组更改为('noun','john')会导致测试失败,因为parse_subject正在寻找'noun'。