Skip to content

12.6 コードのテスト

コードに変更を加えた際に、以前は動作していた部分がおかしくなること(退行、リグレッション)を防ぐため、テストは非常に重要です。手動で print() を使って確認するのも一つの手ですが、本番環境に残してしまうリスクなどを考慮すると、自動化されたテストの仕組みを利用すべきです。

12.6.1 pylintpyflakespep8 によるチェック

Section titled “12.6.1 pylint、pyflakes、pep8 によるチェック”

テストプログラムを書く前に、まずはPythonコードチェッカーを使って静的解析を行いましょう。これらは構文エラーやスタイル上の問題(PEP8違反など)を指摘してくれます。

Terminal window
# インストール
$ pip install pylint
$ pip install pyflakes
$ pip install pep8

たとえば、pylint はコードの品質を10点満点で採点し、未定義の変数の使用や、docstringの欠如、命名規則の違反などを詳細に報告してくれます。

Terminal window
# 実行例
$ pylint my_script.py

Pythonの標準ライブラリに含まれる強力なテストフレームワークが unittest です。

例として、単語の先頭を大文字にする just_do_it 関数(cap.py)をテストしてみましょう。

cap.py
def just_do_it(text):
"""入力されたテキストのすべての単語をタイトルケースにする"""
from string import capwords
return capwords(text)

テストコードは別ファイル(test_cap.py)に作成し、unittest.TestCase を継承したクラス内に test_ で始まるメソッドを定義します。

test_cap.py
import unittest
import cap
class TestCap(unittest.TestCase):
# テストの準備(今回は中身なし)
def setUp(self):
pass
# テストの後処理(今回は中身なし)
def tearDown(self):
pass
def test_one_word(self):
text = 'duck'
result = cap.just_do_it(text)
self.assertEqual(result, 'Duck') # アサーション(期待値の確認)
def test_multiple_words(self):
text = 'a veritable flock of ducks'
result = cap.just_do_it(text)
self.assertEqual(result, 'A Veritable Flock Of Ducks')
if __name__ == '__main__':
unittest.main()

ターミナルからテストを実行すると、成功した場合は .、失敗した場合は F が表示され、エラーの詳細が出力されます。

Terminal window
$ python test_cap.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK

doctest は、docstring(関数の説明文)の中に、対話型インタープリタの実行例のような形式でテストを記述できる標準ライブラリです。ドキュメントとテストを兼ねることができます。

cap.py
def just_do_it(text):
"""
>>> just_do_it('duck')
'Duck'
>>> just_do_it('a veritable flock of ducks')
'A Veritable Flock Of Ducks'
"""
from string import capwords
return capwords(text)
if __name__ == '__main__':
import doctest
doctest.testmod()

実行してエラーがなければ何も表示されません。詳細を見たい場合は -v オプションを付けます。

Terminal window
$ python cap.py -v

サードパーティ製の nose パッケージを使うと、unittest のようにクラスを作る必要がなく、より簡潔にテストを書くことができます。名前に test が含まれる関数が自動的に実行されます。

Terminal window
$ pip install nose
test_cap_nose.py
import cap
from nose.tools import eq_
def test_one_word():
text = 'duck'
result = cap.just_do_it(text)
eq_(result, 'Duck') # unittestの self.assertEqual と同等
def test_multiple_words():
text = 'a veritable flock of ducks'
result = cap.just_do_it(text)
eq_(result, 'A Veritable Flock Of Ducks')

実行には nosetests コマンドを使用します。

Terminal window
$ nosetests test_cap_nose.py

12.6.5 & 12.6.6 その他のツールとCI(継続的インテグレーション)

Section titled “12.6.5 & 12.6.6 その他のツールとCI(継続的インテグレーション)”
  • その他のテストフレームワーク: toxpy.test なども人気があります。
  • CI(継続的インテグレーション): グループ開発などでは、コードをリポジトリにコミットした際に自動的にすべてのテストを実行する仕組みが役立ちます。代表的なツールとして buildbotjenkinstravis-ci などがあります。