Python コードのユニットテスト2016年1月26日 | |
はじめにPython コードのユニットテストについて。 環境
※MinGW にも Python が入っているので、Anaconda のほうを使うようにパスを設定している。 例例として、以下のようなコードを考える。 func.py
def abs(x):
if x >= 0:
return x
else:
return -x
def positive(x):
if x > 0:
return True
else:
return False
テストを書くテストは以下のように書く。 func_test.py
from unittest import TestCase, main
from func import *
class FuncTest(TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_abs(self):
self.assertEqual(abs(1), 1)
self.assertEqual(abs(-1), 1)
def test_positive(self):
self.assertTrue(positive(1))
self.assertTrue(not positive(-1))
if __name__ == '__main__':
main()
TestCase を継承したクラスを作り、その中にテストを書く。setUp() と tearDown() はそれぞれテスト前とテスト後に実行される関数である。assertEqual() は値が等しいことをチェックする関数で、assertTrue() は値が真であることをチェックする関数である。 テストの実行テストを実行するには、次のようにする。 $ python -m unittest -v func_test.FuncTest test_abs (func_test.FuncTest) ... ok test_positive (func_test.FuncTest) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK オプション "-v" は詳細表示の指定である。 テストに失敗すると、次のようになる。
$ python -m unittest -v func_test.FuncTest
test_abs (func_test.FuncTest) ... FAIL
test_positive (func_test.FuncTest) ... ok
======================================================================
FAIL: test_abs (func_test.FuncTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "func_test.py", line 14, in test_abs
self.assertEqual(abs(-1), 1)
AssertionError: -1 != 1
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
カレントディレクトリにあるテストコードを含むファイルをすべて実行させることもできる。テストコードを含むファイル名を "*_test.py" とすると、以下のように実行する。 $ $ python -m unittest discover -p "*_test.py" -v オプション "-p" でテストコードのファイル名のパターンを指定している。 nose の利用nose というテストツールを使うこともできる。 上のテストを次のように書ける。
from unittest import TestCase
from nose.tools import eq_, ok_
from func import *
class FuncTest(TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_abs(self):
eq_(abs(1), 1)
eq_(abs(-1), 1)
def test_positive(self):
ok_(positive(1))
ok_(not positive(-1))
eq_() は assertEqual() の代り、ok_() は assertTrue() の代りである。 テストは次のように実行する。 $ nosetests -v func_test.py test_abs (func_test.FuncTest) ... ok test_positive (func_test.FuncTest) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK オプション "-v" は詳細表示の指定である。nosetests はテストの標準出力を出力させないため、もし出力させたい場合はオプション "-s" を指定する。nosetests は、ファイル名を指定しなければ、カレントディレクトリにある名前からしてテストコードと思われるファイルの中からテストを探して実行してくれる。 テストが失敗した時点でテストを停止したい場合は、オプションで "-x" を指定する。
$ nosetests -v -x
test_abs (func_test.FuncTest) ... FAIL
======================================================================
FAIL: test_abs (func_test.FuncTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\msys64\home\yuyu\unittest\nose\func_test.py", line 15, in test_abs
eq_(abs(-1), 1)
AssertionError: -1 != 1
----------------------------------------------------------------------
Ran 1 test in 0.006s
FAILED (failures=1)
コードカバレッジの計測Coverage があれば、コードカバレッジを測ることができる。 Coverage のインストールは次のようにする。 $ pip install coverage コードカバレッジを計測するには、テストを次のように実行する。 $ coverage run func_test.py 計測結果は次のように得られる。 $ coverage report Name Stmts Miss Cover ---------------------------------- func.py 8 0 100% func_test.py 15 0 100% ---------------------------------- TOTAL 23 0 100% もしテストの範囲が十分でないと、次のようになる。 $ coverage report Name Stmts Miss Cover ---------------------------------- func.py 8 2 75% func_test.py 13 0 100% ---------------------------------- TOTAL 21 2 90% 次のようにすると、HTML を生成してくれる。 $ coverage html htmlconv/index.html をブラウザで開く。この情報を見ると、下図のように、どこを通り損ねているか一目瞭然である。 ![]() Coverage の情報を初期化したい場合は、次のようにする。 $ coverage erase nose の場合nosetests のオプションで "--with-coverage" を指定すると、Coverage を実行してくれる。 $ nosetests -v --with-coverage test_abs (func_test.FuncTest) ... ok test_positive (func_test.FuncTest) ... ok Name Stmts Miss Cover Missing --------------------------------------- func.py 8 0 100% ---------------------------------------------------------------------- Ran 2 tests in 0.009s OK オプション "--cover-html" で HTML 生成を、"--cover-erase" で実行前に erase を実行してくれる。 参考 | |
| PENGUINITIS | |