pythonのunittestで例外の送出を検証する場合はassertRaises
pythonのunittest.TestCaseで例外の送出を検証したいときは
- TestCase.assertRaises
- TestCase.failUnlessRaises
でやる。
試しに上記メソッドで検証した場合と独自にそれっぽい検証メソッドを定義した場合を比較してみる。
# -*- coding:utf-8 -*- import unittest class TheTest(unittest.TestCase): def checkRaise(self, fn, ex_clz): try: fn() except Exception, ex: self.assertEquals(ex_clz, ex.__class__, '期待(%s)と違う例外が送出されています %s: %s' % (ex_clz.__name__, ex.__class__.__name__, ex)) else: self.fail('期待した例外が送出されませんでした') def test_foo(self): self.checkRaise(lambda: [][0], IndexError) def test_bar(self): self.checkRaise(lambda: [][0], ValueError) def test_baz(self): self.checkRaise(lambda: True, IndexError) class SimpleNaTest(unittest.TestCase): def test_hoge(self): self.assertRaises(IndexError, lambda: [][0]) def test_fuga(self): self.assertRaises(ValueError, lambda: [][0]) def test_piyo(self): self.assertRaises(IndexError, lambda: True) def main(*args): unittest.main() if __name__ == '__main__': import sys main(sys.argv[1:])
実行結果は以下の通り。
E.FFF. ====================================================================== ERROR: test_fuga (__main__.SimpleNaTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "baz.py", line 28, in test_fuga self.assertRaises(ValueError, lambda: [][0]) File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/unittest.py", line 336, in failUnlessRaises callableObj(*args, **kwargs) File "baz.py", line 28, in <lambda> self.assertRaises(ValueError, lambda: [][0]) IndexError: list index out of range ====================================================================== FAIL: test_piyo (__main__.SimpleNaTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "baz.py", line 31, in test_piyo self.assertRaises(IndexError, lambda: True) AssertionError: IndexError not raised ====================================================================== FAIL: test_bar (__main__.TheTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "baz.py", line 18, in test_bar self.checkRaise(lambda: [][0], ValueError) File "baz.py", line 10, in checkRaise self.assertEquals(ex_clz, ex.__class__, '期待(%s)と違う例外が送出されています %s: %s' % (ex_clz.__name__, ex.__class__.__name__, ex)) AssertionError: 期待(ValueError)と違う例外が送出されています IndexError: list index out of range ====================================================================== FAIL: test_baz (__main__.TheTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "baz.py", line 21, in test_baz self.checkRaise(lambda: True, IndexError) File "baz.py", line 12, in checkRaise self.fail('期待した例外が送出されませんでした') AssertionError: 期待した例外が送出されませんでした ---------------------------------------------------------------------- Ran 6 tests in 0.001s FAILED (failures=3, errors=1)
SimpleNaTest.test_fugaがFailでなくErrorになるが、あまり気にする必要はないと思う。
(どっちでもどうせテストが通らないから)
ちなみに、assertRaises, assertUnlessRaisesで期待される例外が複数ある場合は例外のタプルを渡すらしい。
self.assertRaises((ValueError, IndexError), lambda: [][0])
こんな風に。
参考: http://www.python.jp/doc/2.6/library/unittest.html#unittest.TestCase.assertRaises