Python: ユニットテストの実行
このページ(Dive Into Python)が分かりやすかった。
http://diveintopython3-ja.rdy.jp/unit-testing.html
Pythonでは、テスト駆動開発(TDD/Test-Driven Development)に必要なツールが標準で用意されている。
以下の手順で実行。
・unittest モジュールをインポート
・「unittest.TestCase」を継承するクラスを作成
・「test」で始まる名前のクラスメソッドを作成
・そのメソッドの中でテストしたい処理を実行 ⇒ 例外が発生せずメソッドが完了すれば、テストOKとなる
・同値性の確認:self.assertEqual(first, second)
・特定の例外が発生することの確認:self.assertRaises(excClass)
⇒ with ステートメントを使うと非常にスマートなコーディングができる。
・unittest.main() を実行
以上を踏まえ、将棋の駒クラスのユニットテストを実装。
・test_piece.py
#!/usr/bin/python2.7
# Copyright (c) 2011 Mog Project. All rights reserved.
from shogi.piece import Piece
from shogi.piece import PieceError
import unittest
class Test(unittest.TestCase):
# csa, owner, type, origin, reverse, promote
all_pieces = (
(None, ' ', '* ', ' * ', ' * ', None),
(' * ', ' ', '* ', ' * ', ' * ', None),
(' XX', ' ', '* ', ' * ', ' * ', None),
('+FU', '+', 'FU', '+FU', '-FU', '+TO'),
('+KY', '+', 'KY', '+KY', '-KY', '+NY'),
('+KE', '+', 'KE', '+KE', '-KE', '+NK'),
('+GI', '+', 'GI', '+GI', '-GI', '+NG'),
('+KI', '+', 'KI', '+KI', '-KI', None),
('+KA', '+', 'KA', '+KA', '-KA', '+UM'),
('+HI', '+', 'HI', '+HI', '-HI', '+RY'),
('+OU', '+', 'OU', '+OU', '-OU', None),
('+TO', '+', 'TO', '+FU', '-TO', None),
('+NY', '+', 'NY', '+KY', '-NY', None),
('+NK', '+', 'NK', '+KE', '-NK', None),
('+NG', '+', 'NG', '+GI', '-NG', None),
('+UM', '+', 'UM', '+KA', '-UM', None),
('+RY', '+', 'RY', '+HI', '-RY', None),
('-FU', '-', 'FU', '-FU', '+FU', '-TO'),
('-KY', '-', 'KY', '-KY', '+KY', '-NY'),
('-KE', '-', 'KE', '-KE', '+KE', '-NK'),
('-GI', '-', 'GI', '-GI', '+GI', '-NG'),
('-KI', '-', 'KI', '-KI', '+KI', None),
('-KA', '-', 'KA', '-KA', '+KA', '-UM'),
('-HI', '-', 'HI', '-HI', '+HI', '-RY'),
('-OU', '-', 'OU', '-OU', '+OU', None),
('-TO', '-', 'TO', '-FU', '+TO', None),
('-NY', '-', 'NY', '-KY', '+NY', None),
('-NK', '-', 'NK', '-KE', '+NK', None),
('-NG', '-', 'NG', '-GI', '+NG', None),
('-UM', '-', 'UM', '-KA', '+UM', None),
('-RY', '-', 'RY', '-HI', '+RY', None),
)
def test_all(self):
print '[All pieces]'
for csa, owner, type_, origin, reverse, promote in self.all_pieces:
print csa, owner, type_, origin, reverse, promote
p = Piece() if not csa else Piece(csa)
self.assertEqual(str(p), '%s%s' % (owner, type_))
self.assertEqual(repr(p), "Piece('%s%s')" % (owner, type_))
self.assertEqual(p.owner(), owner)
self.assertEqual(p.type_(), type_)
self.assertEqual(p.origin(), Piece(origin))
self.assertEqual(p.reverse(), Piece(reverse))
self.assertEqual(p.is_promotable(), promote != None)
if promote:
self.assertEqual(p.promote(), Piece(promote))
def test_initialize_error(self):
print '[Initialize errors]'
for csa in ('', ' ', '-', 'SPAM', '=FU', '+Fu', 0):
with self.assertRaises(PieceError) as cm:
Piece(csa)
print cm.exception
def test_modify_error(self):
print '[Modify error]'
with self.assertRaises(TypeError) as cm:
x = Piece('+FU')
x.csa = '-FU'
print cm.exception
def test_delete_error(self):
print '[Delete error]'
with self.assertRaises(TypeError) as cm:
x = Piece('+FU')
del x.csa
print cm.exception
def test_promote_error(self):
print '[Promote errors]'
for x in (None, '+', '-'):
for y in ('OU', 'KI', 'TO', 'NY', 'NK', 'NG', 'UM', 'RY'):
with self.assertRaises(PieceError) as cm:
if not x:
Piece().promote()
else:
Piece(x + y).promote()
print cm.exception
if not x: break
if __name__ == "__main__":
unittest.main()
・出力結果(Eclipse + Pydev で実行)
pydev debugger: warning: psyco not available for speedups (the debugger will still work correctly, but a bit slower) pydev debugger: starting Finding files... done. Importing test modules ... done.
[All pieces] None * * * None * * * * None XX * * * None +FU + FU +FU -FU +TO +KY + KY +KY -KY +NY +KE + KE +KE -KE +NK +GI + GI +GI -GI +NG +KI + KI +KI -KI None +KA + KA +KA -KA +UM +HI + HI +HI -HI +RY +OU + OU +OU -OU None +TO + TO +FU -TO None +NY + NY +KY -NY None +NK + NK +KE -NK None +NG + NG +GI -NG None +UM + UM +KA -UM None +RY + RY +HI -RY None -FU - FU -FU +FU -TO -KY - KY -KY +KY -NY -KE - KE -KE +KE -NK -GI - GI -GI +GI -NG -KI - KI -KI +KI None -KA - KA -KA +KA -UM -HI - HI -HI +HI -RY -OU - OU -OU +OU None -TO - TO -FU +TO None -NY - NY -KY +NY None -NK - NK -KE +NK None -NG - NG -GI +NG None -UM - UM -KA +UM None -RY - RY -HI +RY None [Delete error] piece object is read-only [Initialize errors] piece type error ('') piece type error (' ') piece type error ('-') piece type error ('SPAM') piece type error ('=FU') piece type error ('+Fu') piece type error (0) [Modify error] piece object is read-only [Promote errors] unpromotable piece ( * ) unpromotable piece (+OU) unpromotable piece (+KI) unpromotable piece (+TO) unpromotable piece (+NY) unpromotable piece (+NK) unpromotable piece (+NG) unpromotable piece (+UM) unpromotable piece (+RY) unpromotable piece (-OU) unpromotable piece (-KI) unpromotable piece (-TO) unpromotable piece (-NY) unpromotable piece (-NK) unpromotable piece (-NG) unpromotable piece (-UM) unpromotable piece (-RY) ---------------------------------------------------------------------- Ran 5 tests in 0.058s
OK |