我用鼻子测试异常。这是一个例子:
def testDeleteUserUserNotFound(self):
"Test exception is raised when trying to delete non-existent users"
try:
self.client.deleteUser('10000001-0000-0000-1000-100000000000')
# make nose fail here
except UserNotFoundException:
assert True
如果引发异常,则执行assert,但如果没有引发异常,则不会执行。
我可以在上面的注释行中添加任何内容,以便如果没有异常,则会报告失败吗?
答案 0 :(得分:45)
nose 提供了测试异常的工具(比如unittest)。 试试这个例子(并阅读Nose Testing Tools
中的其他工具from nose.tools import *
l = []
d = dict()
@raises(Exception)
def test_Exception1():
'''this test should pass'''
l.pop()
@raises(KeyError)
def test_Exception2():
'''this test should pass'''
d[1]
@raises(KeyError)
def test_Exception3():
'''this test should fail (IndexError raised but KeyError was expected)'''
l.pop()
def test_Exception4():
'''this test should fail with KeyError'''
d[1]
我认为这是您正在寻找的正确方式,因为它可以让您具体了解您期望或想要的异常。所以你实际上引发了错误,看到它引发了正确的异常。然后你让鼻子评估结果。 (尽可能少地将逻辑放入单元测试中!)
答案 1 :(得分:9)
def testDeleteUserUserNotFound(self):
"Test exception is raised when trying to delete non-existent users"
try:
self.client.deleteUser('10000001-0000-0000-1000-100000000000')
assert False # <---
except UserNotFoundException:
assert True
try
/ except
的语义意味着执行流程将try
块留在异常上,因此如果引发异常,assert False
将不会运行。此外,在try
块运行完毕后,执行不会再次重新进入except
块,因此您不应该遇到麻烦。
↓
(statements)
↓ exception
(try) ↚──────────→ (except)
↓ │
(statements) ←───────────┘
↓
答案 2 :(得分:9)
我强烈建议您使用assert_raises
中的assert_raises_regexp
和nose.tools
,unittest.TestCase
与unittest.TestCase
的{{3}}和assertRaises
的行为相同。这些允许使用unittest.TestCase
在未实际使用@raises
类的测试套件中提供的相同功能。
我发现from nose.tools import *
something = ["aaa", "bbb"]
def foo(x, source=None):
if source is None:
source = something
return source[x]
# This is fine
@raises(IndexError)
def test1():
foo(3)
# This is fine. The expected error does not happen because we made
# a mistake in the test or in the code. The failure indicates we made
# a mistake.
@raises(IndexError)
def test2():
foo(1)
# This passes for the wrong reasons.
@raises(IndexError)
def test3():
source = something[2] # This is the line that raises the exception.
foo(10, source) # This is not tested.
# When we use assert_raises, we can isolate the line where we expect
# the failure. This causes an error due to the exception raised in
# the first line of the function.
def test4():
source = something[2]
with assert_raises(IndexError):
foo(10, source)
是一种过于生硬的工具。以下是说明问题的代码:
test3
foo
已通过,但不是因为foo
引发了我们期望的异常,而是因为设置test4
要使用的数据的代码失败并出现相同的异常。 assert_raises
显示了如何使用@raises
来编写测试来实际测试我们要测试的内容。第一行的问题会导致Nose报告错误,然后我们可以重写测试,以便我们可以最终测试我们测试的意思。
ValueError
不允许测试与异常关联的消息。当我举起def bar(arg):
if arg: # This is incorrect code.
raise ValueError("arg should be higher than 3")
if arg >= 10:
raise ValueError("arg should be less than 10")
# We don't know which of the possible `raise` statements was reached.
@raises(ValueError)
def test5():
bar(10)
# Yes, we're getting an exception but with the wrong value: bug found!
def test6():
with assert_raises_regexp(ValueError, "arg should be less than 10"):
bar(10)
时,举一个例子,我通常想要提供一条信息性的信息。这是一个例子:
test5
使用@raises
的 test6
会通过,但会因错误原因而通过。 ValueError
执行更精细的测试,结果显示val max: Option[Int] = Seq(l1, l2, l3, l4).flatten.reduceOption(_ max _)
筹集的不是我们想要的。
答案 3 :(得分:7)
我不知道为什么它不在这里,但又存在一种方式:
import unittest
class TestCase(unittest.TestCase):
def testKeyError(self):
d = dict()
with self.assertRaises(KeyError):
d[1]
答案 4 :(得分:3)
使用assert_raises
:
from nose.tools import assert_raises
our_method = self.client.deleteUser
arg1 = '10000001-0000-0000-1000-100000000000'
expected_exception = UserNotFoundException
assert_raises(expected_exception, our_method, arg1)
在测试中使用try和catch似乎是不好的做法(大多数情况下)。
鼻子中没有特定的文档,因为它基本上只是unittest.TestCase.assertRaises的一个包装(参考How to use nose's assert_raises?)
答案 5 :(得分:1)
我不知道鼻子是什么,但你是否尝试在except子句后使用'else'。即
else:
assert False