如何编写只有在函数没有抛出预期异常时才会失败的单元测试呢?
当前回答
我刚刚发现Mock库提供了一个assertRaisesWithMessage()方法(在其unittest中)。TestCase子类),它不仅会检查是否引发了预期的异常,还会检查它是否与预期的消息一起引发:
from testcase import TestCase
import mymod
class MyTestCase(TestCase):
def test1(self):
self.assertRaisesWithMessage(SomeCoolException,
'expected message',
mymod.myfunc)
其他回答
使用TestCase。从unittest模块中assertRaises(或testcase . failunlessraised),例如:
import mymod
class MyTestCase(unittest.TestCase):
def test1(self):
self.assertRaises(SomeCoolException, mymod.myfunc)
对于await/async aiounittest有一个稍微不同的模式:
https://aiounittest.readthedocs.io/en/latest/asynctestcase.html#aiounittest.AsyncTestCase
async def test_await_async_fail(self):
with self.assertRaises(Exception) as e:
await async_one()
你可以使用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)
如果你正在使用pytest,你可以使用pytest.raise (Exception):
例子:
def test_div_zero():
with pytest.raises(ZeroDivisionError):
1/0
结果是:
$ py.test
================= test session starts =================
platform linux2 -- Python 2.6.6 -- py-1.4.20 -- pytest-2.5.2 -- /usr/bin/python
collected 1 items
tests/test_div_zero.py:6: test_div_zero PASSED
或者你可以构建自己的上下文管理器来检查异常是否被引发。
import contextlib
@contextlib.contextmanager
def raises(exception):
try:
yield
except exception as e:
assert True
else:
assert False
然后你可以像这样使用加薪:
with raises(Exception):
print "Hola" # Calls assert False
with raises(Exception):
raise Exception # Calls assert True
有4个选项(你会在最后找到完整的例子):
assertRaises与上下文管理器
def test_raises(self):
with self.assertRaises(RuntimeError):
raise RuntimeError()
如果你想检查异常消息(参见下面的"assertRaisesRegex with context manager"选项来检查它的一部分):
def test_raises(self):
with self.assertRaises(RuntimeError) as error:
raise RuntimeError("your exception message")
self.assertEqual(str(error.exception), "your exception message")
assertRaises一行程序
注意:这里使用的函数不是函数调用,而是可调用函数(不带圆括号)。
def test_raises(self):
self.assertRaises(RuntimeError, your_function)
assertRaisesRegex与上下文管理器
第二个参数是正则表达式,是必选项。当您只想检查部分异常消息时,非常方便。
def test_raises_regex(self):
with self.assertRaisesRegex(RuntimeError, r'.* exception message'):
raise RuntimeError('your exception message')
assertRaisesRegex一行程序
第二个参数是正则表达式,是必选项。当您只想检查部分异常消息时,非常方便。
注意:这里使用的函数不是函数调用,而是可调用函数(不带圆括号)。
def test_raises_regex(self):
self.assertRaisesRegex(RuntimeError, r'.* exception message', your_function)
完整的代码示例:
import unittest
def your_function():
raise RuntimeError('your exception message')
class YourTestCase(unittest.TestCase):
def test_1_raises_context_manager(self):
with self.assertRaises(RuntimeError):
your_function()
def test_1b_raises_context_manager_and_error_message(self):
with self.assertRaises(RuntimeError) as error:
your_function()
self.assertEqual(str(error.exception), "your exception message")
def test_2_raises_oneliner(self):
self.assertRaises(RuntimeError, your_function)
def test_3_raises_regex_context_manager(self):
with self.assertRaisesRegex(RuntimeError, r'.* exception message'):
your_function()
def test_4_raises_regex_oneliner(self):
self.assertRaisesRegex(RuntimeError, r'.* exception message', your_function)
if __name__ == '__main__':
unittest.main()
虽然这取决于开发人员遵循哪种风格,但我更喜欢使用上下文管理器的两种方法。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if