你如何testing一个Python函数抛出一个exception?
如何编写一个unittest,只有当一个函数没有抛出预期的exception时才会失败?
使用unittest模块中的TestCase.assertRaises (或TestCase.failUnlessRaises ),例如: 
 import mymod class MyTestCase(unittest.TestCase): def test1(self): self.assertRaises(SomeCoolException, mymod.myfunc) 
从Python 2.7开始,您可以使用上下文pipe理器来获取抛出的实际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() 
http://docs.python.org/dev/library/unittest.html#unittest.TestCase.assertRaises
 在Python 3.5中 ,你必须在str包装context.exception ,否则你会得到一个TypeError 
 self.assertTrue('This is broken' in str(context.exception)) 
我以前的答案中的代码可以简化为:
 def test_afunction_throws_exception(self): self.assertRaises(ExpectedException, afunction) 
如果函数有参数,只需将它们传递给assertRaises就可以了:
 def test_afunction_throws_exception(self): self.assertRaises(ExpectedException, afunction, arg1, arg2) 
你如何testing一个Python函数抛出一个exception?
如何编写一个只有在函数不抛出预期exception的情况下才会失败的testing?
简答:
 使用self.assertRaises方法作为上下文pipe理器: 
  def test_1_cannot_add_int_and_str(self): with self.assertRaises(TypeError): 1 + '1' 
示范
最佳实践方法在Python shell中很容易演示。
unit testing库
在Python 2.7或3中:
 import unittest 
在Python 2.6中,你可以安装一个名为unittest2的2.7unit testing库的backport,并且将其作为unit testing的别名:
 import unittest2 as unittest 
示例testing
现在,将Python的types安全性testing粘贴到您的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') 
 testing人员使用assertRaises作为上下文pipe理器,确保在logging时正确捕获和清除错误。 
我们也可以在没有上下文pipe理器的情况下编写它,参见testing二。 第一个参数是你期望提出的错误types,第二个参数,你正在testing的函数,其余的参数和关键字参数将被传递给该函数。
我认为它更简单,更易读,更易于使用上下文pipe理器。
运行testing
运行testing:
 unittest.main(exit=False) 
在Python 2.6中,您可能需要以下内容 :
 unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase)) 
你的terminal应该输出以下内容:
 .. ---------------------------------------------------------------------- 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)) 
你的代码应该遵循这个模式(这是一个unit testing模块风格testing):
 def test_afunction_throws_exception(self): try: afunction() except ExpectedException: pass except Exception as e: self.fail('Unexpected exception raised:', e) else: self.fail('ExpectedException not raised') 
 在Python <2.7这个结构对检查预期exception中的特定值很有用。  unittest函数assertRaises只检查是否引发exception。 
我几乎在任何地方都使用doctest [1],因为我喜欢同时logging和testing我的function的事实。
看看这个代码:
 def throw_up(something, gowrong=False): """ >>> throw_up('Fish n Chips') Traceback (most recent call last): ... Exception: Fish n Chips >>> throw_up('Fish n Chips', gowrong=True) 'I feel fine!' """ if gowrong: return "I feel fine!" raise Exception(something) if __name__ == '__main__': import doctest doctest.testmod() 
如果你把这个例子放在一个模块中并从命令行运行,那么这两个testing用例都将被评估和检查。
[1] Python文档:23.2 doctest – testing交互式Python示例
来自: http : //www.lengrand.fr/2011/12/pythonunittest-assertraises-raises-error/
首先,这里是文件dum_function.py中相应的(仍然是dum:p)函数:
 def square_value(a): """ Returns the square value of a. """ try: out = a*a except TypeError: raise TypeError("Input should be a string:") return out 
这里是要执行的testing(只有这个testing被插入):
 import dum_function as df # import function module import unittest class Test(unittest.TestCase): """ The class inherits from unittest """ def setUp(self): """ This method is called before each test """ self.false_int = "A" def tearDown(self): """ This method is called after each test """ pass #--- ## TESTS def test_square_value(self): # assertRaises(excClass, callableObj) prototype self.assertRaises(TypeError, df.square_value(self.false_int)) if __name__ == "__main__": unittest.main() 
我们现在准备testing我们的function! 这是试图运行testing时发生的事情:
 ====================================================================== ERROR: test_square_value (__main__.Test) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_dum_function.py", line 22, in test_square_value self.assertRaises(TypeError, df.square_value(self.false_int)) File "/home/jlengrand/Desktop/function.py", line 8, in square_value raise TypeError("Input should be a string:") TypeError: Input should be a string: ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) 
TypeError被动作提出,并产生一个testing失败。 问题是,这正是我们想要的行为:s。
为了避免这个错误,只需在testing调用中使用lambda来运行函数:
 self.assertRaises(TypeError, lambda: df.square_value(self.false_int)) 
最终输出:
 ---------------------------------------------------------------------- Ran 1 test in 0.000s OK 
完美!
…对我来说也是完美的!
Thansk很多Julien Lengrand-Lambert先生
 看看unittest模块的assertRaises方法。 
我刚刚发现, Mock库提供了一个assertRaisesWithMessage()方法(在它的unittest.TestCase子类中),它不仅检查期望的exception是否被引发,而且还会引发预期的消息:
 from testcase import TestCase import mymod class MyTestCase(TestCase): def test1(self): self.assertRaisesWithMessage(SomeCoolException, 'expected message', mymod.myfunc) 
 您可以构build自己的contextmanager来检查是否引发exception。 
 import contextlib @contextlib.contextmanager def raises(exception): try: yield except exception as e: assert True else: assert False 
 然后你可以使用像这样的raises : 
 with raises(Exception): print "Hola" # Calls assert False with raises(Exception): raise Exception # Calls assert True 
 如果你正在使用pytest ,这个东西已经实现了。 你可以做pytest.raises(Exception) : 
例:
 def test_div_zero(): with pytest.raises(ZeroDivisionError): 1/0 
结果是:
 pigueiras@pigueiras$ 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 
你可以使用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 dont use () when passing the method to assertRaises self.assertRaises(Exception, test_class.raises_exception) 
- .Net处理exception时常见的编程错误?
- 在ASP.NET Web Api中捕获所有未处理的exception
- 如何防止后台线程中的exception终止应用程序?
- '+ entityForName:nil不是合法的NSManagedObjectContext参数 – 核心数据
- 如何从“需求”中拯救:没有这样的文件加载在ruby?
- Java – 在try / catch中执行try / catch是不好的做法吗?
- locking的对象是否locking,如果内部发生exception?
- 排除BadImageFormatExceptionexception
- 如何find在C ++中抛出exception?