如何编写只有在函数没有抛出预期异常时才会失败的单元测试呢?
当前回答
这里有很多答案。该代码展示了如何创建Exception,如何在方法中使用该异常,以及如何在单元测试中验证所引发的正确异常。
import unittest
class DeviceException(Exception):
def __init__(self, msg, code):
self.msg = msg
self.code = code
def __str__(self):
return repr("Error {}: {}".format(self.code, self.msg))
class MyDevice(object):
def __init__(self):
self.name = 'DefaultName'
def setParameter(self, param, value):
if isinstance(value, str):
setattr(self, param , value)
else:
raise DeviceException('Incorrect type of argument passed. Name expects a string', 100001)
def getParameter(self, param):
return getattr(self, param)
class TestMyDevice(unittest.TestCase):
def setUp(self):
self.dev1 = MyDevice()
def tearDown(self):
del self.dev1
def test_name(self):
""" Test for valid input for name parameter """
self.dev1.setParameter('name', 'MyDevice')
name = self.dev1.getParameter('name')
self.assertEqual(name, 'MyDevice')
def test_invalid_name(self):
""" Test to check if error is raised if invalid type of input is provided """
self.assertRaises(DeviceException, self.dev1.setParameter, 'name', 1234)
def test_exception_message(self):
""" Test to check if correct exception message and code is raised when incorrect value is passed """
with self.assertRaises(DeviceException) as cm:
self.dev1.setParameter('name', 1234)
self.assertEqual(cm.exception.msg, 'Incorrect type of argument passed. Name expects a string', 'mismatch in expected error message')
self.assertEqual(cm.exception.code, 100001, 'mismatch in expected error code')
if __name__ == '__main__':
unittest.main()
其他回答
如果在这个类中将stock_id设置为Integer将抛出错误,则将引发TypeError,如果发生这种情况,则测试将通过,否则将失败
def set_string(prop, value):
if not isinstance(value, str):
raise TypeError("i told you i take strings only ")
return value
class BuyVolume(ndb.Model):
stock_id = ndb.StringProperty(validator=set_string)
from pytest import raises
buy_volume_instance: BuyVolume = BuyVolume()
with raises(TypeError):
buy_volume_instance.stock_id = 25
你的代码应该遵循这个模式(这是一个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只检查是否引发了异常。
从Python 2.7开始,你可以使用上下文管理器来获取实际抛出的Exception对象:
import unittest
def broken_function():
raise Exception('This is broken')
class MyTestCase(unittest.TestCase):
def test(self):
with self.assertRaises(Exception) as context:
broken_function()
self.assertTrue('This is broken' in context.exception)
if __name__ == '__main__':
unittest.main()
断言
在Python 3.5中,必须对上下文进行包装。否则你会得到一个TypeError
self.assertTrue('This is broken' in str(context.exception))
如果你正在使用Python 3,为了断言异常及其消息,你可以在上下文管理器中使用assertRaises,并将消息作为msg关键字参数传递,如下所示:
import unittest
def your_function():
raise RuntimeError('your exception message')
class YourTestCase(unittest.TestCase):
def test(self):
with self.assertRaises(RuntimeError, msg='your exception message'):
your_function()
if __name__ == '__main__':
unittest.main()
虽然所有的答案都很好,但我正在寻找一种方法来测试一个函数是否引发了异常,而不依赖于单元测试框架,也不必编写测试类。
最后我写下了以下内容:
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
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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