如何编写只有在函数没有抛出预期异常时才会失败的单元测试呢?
当前回答
对于Django上的那些,你可以使用上下文管理器来运行错误的函数,并使用assertRaisesMessage断言它会引发带有特定消息的异常
with self.assertRaisesMessage(SomeException,'Some error message e.g 404 Not Found'):
faulty_funtion()
其他回答
虽然所有的答案都很好,但我正在寻找一种方法来测试一个函数是否引发了异常,而不依赖于单元测试框架,也不必编写测试类。
最后我写下了以下内容:
def assert_error(e, x):
try:
e(x)
except:
return
raise AssertionError()
def failing_function(x):
raise ValueError()
def dummy_function(x):
return x
if __name__=="__main__":
assert_error(failing_function, 0)
assert_error(dummy_function, 0)
它在右边行上失败了:
Traceback (most recent call last):
File "assert_error.py", line 16, in <module>
assert_error(dummy_function, 0)
File "assert_error.py", line 6, in assert_error
raise AssertionError()
AssertionError
如何测试Python函数是否抛出异常? 如何编写只有在函数不抛出时才会失败的测试呢 意料之中的例外?
简短的回答:
利用自我。assertRaises方法作为上下文管理器:
def test_1_cannot_add_int_and_str(self):
with self.assertRaises(TypeError):
1 + '1'
示范
在Python shell中很容易演示最佳实践方法。
unittest库
在Python 2.7或3中:
import unittest
在Python 2.6中,你可以安装2.7的unittest库的backport,称为unittest2,并将其别名为unittest:
import unittest2 as unittest
示例测试
现在,将以下Python类型安全测试粘贴到Python shell中:
class MyTestCase(unittest.TestCase):
def test_1_cannot_add_int_and_str(self):
with self.assertRaises(TypeError):
1 + '1'
def test_2_cannot_add_int_and_str(self):
import operator
self.assertRaises(TypeError, operator.add, 1, '1')
测试一使用assertRaises作为上下文管理器,以确保在记录错误的同时正确地捕获和清除错误。
我们也可以在没有上下文管理器的情况下编写它,参见测试二。第一个参数是您期望引发的错误类型,第二个参数是您正在测试的函数,其余的args和关键字args将被传递给该函数。
我认为仅仅使用上下文管理器要简单得多,可读性和可维护性更强。
运行测试
要运行测试:
unittest.main(exit=False)
在Python 2.6中,您可能需要以下内容:
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
你的终端应该输出如下:
..
----------------------------------------------------------------------
Ran 2 tests in 0.007s
OK
<unittest2.runner.TextTestResult run=2 errors=0 failures=0>
正如我们所期望的那样,尝试在TypeError中添加一个1和一个'1'结果。
想要更详细的输出,试试这个:
unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
你的代码应该遵循这个模式(这是一个unittest模块风格测试):
def test_afunction_throws_exception(self):
try:
afunction()
except ExpectedException:
pass
except Exception:
self.fail('unexpected exception raised')
else:
self.fail('ExpectedException not raised')
在Python < 2.7中,此构造用于检查预期异常中的特定值。unittest函数assertRaises只检查是否引发了异常。
你可以使用unittest模块中的assertRaises:
import unittest
class TestClass():
def raises_exception(self):
raise Exception("test")
class MyTestCase(unittest.TestCase):
def test_if_method_raises_correct_exception(self):
test_class = TestClass()
# Note that you don’t use () when passing the method to assertRaises
self.assertRaises(Exception, test_class.raises_exception)
对于Django上的那些,你可以使用上下文管理器来运行错误的函数,并使用assertRaisesMessage断言它会引发带有特定消息的异常
with self.assertRaisesMessage(SomeException,'Some error message e.g 404 Not Found'):
faulty_funtion()
推荐文章
- 如何直接从测试驱动程序调用自定义的Django manage.py命令?
- 我如何让红宝石打印一个完整的回溯而不是截断一个?
- Visual Studio:如何打破处理异常?
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何在Flask-SQLAlchemy中按id删除记录
- 在Python中插入列表的第一个位置
- Python Pandas只合并某些列
- 如何在一行中连接两个集而不使用“|”
- 从字符串中移除前缀
- 代码结束时发出警报
- 如何在Python中按字母顺序排序字符串中的字母
- 在matplotlib中将y轴标签添加到次要y轴
- 如何消除数独方块的凹凸缺陷?
- 为什么出现这个UnboundLocalError(闭包)?
- 使用Python请求的异步请求