python unittestのテンプレート

# 背景
pythonには標準モジュールの中にunittestが含まれるのですが、使い方がすぐに分からなかったため、他のプロジェクトでもコピペできるようにテンプレートを備忘録として残しておきます。

__*注意事項__

python2.7以上からunittestではsetUpClass, tearDownClassというテストクラスの初期化時に実行されるメソッドを用いることができるようになりました。
python2.6以下の場合は、unittest2というモジュールをインポートすることでこれらのメソッドを使うことができます。

# コードのテンプレート

ポイント
* unittest.main()では、setUpClass → (setUp → tearDown) *ループ → tearDownClass が実行されます。
* test用のメソッドは名前の先頭を test から始めなければなりません。e.g. test_hoge()
* assertメソッドはさまざまな種類が用意されているので、[pythonのドキュメント](http://docs.python.jp/2/library/unittest.html#assert-methods)等を参考にしてください。

```py
# -*- coding: utf-8 -*-
import os, sys, unittest

class Sample():
	"""テスト対象のクラス"""
	# テスト対象のメソッド
	def return_hoge(self):
		return 'hoge'

	# テスト対象のメソッド
	def return_poyo(self):
		return 'poyo'

class SampleTest(unittest.TestCase):
	"""あるクラスをテストするテストクラス"""
	CLS_VAL = 'none'

	# テストクラスが初期化される際に一度だけ呼ばれる (python2.7以上)
	@classmethod
	def setUpClass(cls):
		if sys.flags.debug: print('> setUpClass method is called.')
		# テストの準備するための重い処理のメソッドを実行
		cls.CLS_VAL = '> setUpClass : initialized!'
		if sys.flags.debug: print(cls.CLS_VAL)

	# テストクラスが解放される際に一度だけ呼ばれる (python2.7以上)
	@classmethod
	def tearDownClass(cls):
		if sys.flags.debug: print('> tearDownClass method is called.')
		# setUpClassで準備したオブジェクトを解放する
		cls.CLS_VAL = '> tearDownClass : released!'
		if sys.flags.debug: print(cls.CLS_VAL)

	# テストメソッドを実行するたびに呼ばれる
	def setUp(self):
		if sys.flags.debug: print(os.linesep + '> setUp method is called.')
		# テストの準備をするための軽い処理を実行
		self.smpl = Sample()

	# テストメソッドの実行が終わるたびに呼ばれる
	def tearDown(self):
		if sys.flags.debug: print(os.linesep + '> tearDown method is called.')
		# setUpで準備したオブジェクトを解放する

	def test_hoge(self):
		expected = 'hoge'
		actual = self.smpl.return_hoge()
		self.assertEqual(expected, actual)

	def test_poyo(self):
		expected = 'poyo'
		actual = self.smpl.return_hoge() # 凡ミス
		self.assertEqual(expected, actual)

if __name__ == '__main__':
	# unittestを実行
	unittest.main()
```

[gitHubから](https://github.com/Go-zen-chu/PyUnitTestSample)


# 実行結果

pythonスクリプト実行時に -d フラグをつけるとデバッグモードになります。
(sys.flags.debug が True になります。)

```shell-session
python -d /Users/you/Desktop/sample.py

> setUpClass method is called.
> setUpClass : heavy method

> setUp method is called.

> tearDown method is called.
.
> setUp method is called.
F
> tearDown method is called.
> tearDownClass method is called.
> tearDownClass : released

======================================================================
FAIL: test_poyo (__main__.SampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/you/Desktop/sample.py", line 54, in test_poyo
    self.assertEqual(expected, actual)
AssertionError: 'poyo' != 'hoge'

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)
```

デバッグモードにしない場合の出力

```shell-session
 python /Users/you/Desktop/sample.py
.F
======================================================================
FAIL: test_poyo (__main__.SampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/you/Desktop/sample.py", line 54, in test_poyo
    self.assertEqual(expected, actual)
AssertionError: 'poyo' != 'hoge'

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (failures=1)
```


# Appendix

小さなスクリプトではあまり使わないと思いますが、必要な方はsetUpModuleなどModule単位での初期化メソッドもあります。