Nose を使ったテスト¶
前の章ではテストの実行関数をファイルごとに呼び出していました。 ファイルが増えてくると個別に if __name__ == '__main__': を記述するのは煩雑なので、 テストの実行には nose というモジュールを使います。
Nose のインストール¶
requirements.txt に nose の記述を追加して、 pip を使ってインストールします。 インストールできると、 nosetests が使えるようになります。
$ echo "nose" >> requirements.txt
$ pip install -r requirements.txt
$ nosetests -V
nosetests version 1.3.3
--help オプションを付けて実行すると利用可能なオプションを一覧で確認できます。
簡単な実行方法¶
nosetests は test から始まる関数を自動で認識してくれます。 標準モジュールを使ったテスト で記述したスクリプトにはテストが含まれていますので、まずは確認してみます。
$ nosetests --collect-only -v
test (fibonacci_test.FibonacciTest) ... ok
test (fibonacci_test2.FibonacciTest) ... ok
test_invalid_argument (fibonacci_test2.FibonacciTest) ... ok
test (fibonacci_test3.FibonacciTest) ... ok
test_invalid_argument (fibonacci_test3.FibonacciTest) ... ok
test_引数が日本語の場合は? (fibonacci_test3.FibonacciTest) ... ok
fibonacci_test3.test_undefined ... ok
----------------------------------------------------------------------
Ran 7 tests in 0.016s
OK
複数のスクリプトからテストケースを収集できていることが分かります。 実際に実行してみます。(標準エラー出力の内容をテキストファイルに書き出します。)
$ nosetests -v 2>tests.txt
$ head -n 10 tests.txt
test (fibonacci_test.FibonacciTest) ... ok
test (fibonacci_test2.FibonacciTest) ... ok
test_invalid_argument (fibonacci_test2.FibonacciTest) ... ok
test (fibonacci_test3.FibonacciTest) ... ok
test_invalid_argument (fibonacci_test3.FibonacciTest) ... ok
test_引数が日本語の場合は? (fibonacci_test3.FibonacciTest) ... ERROR
fibonacci_test3.test_undefined ... ERROR
======================================================================
$ tail -n 5 tests.txt
----------------------------------------------------------------------
Ran 8 tests in 0.269s
FAILED (errors=3)
前回もエラーだったテストは確かにエラーになっています。 出力結果はファイルに書き出されていますので、最後まで読んでみてください。
レポーティング¶
継続的にテストを実行させる場合、それぞれの実行結果をどのように保存すべきを考える必要があります。 多くの場合は Jenkins などの CI ツールでジョブを自動化することになるでしょう。 こうした CI ツールの多くは xUnit のレポートを表示できます。 nosetests の方でも XML 形式のレポートを出力できるようになっています。
$ nosetests --with-xunit
$ xmllint --format nosetests.xml |head -n 5
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="nosetests" tests="7" errors="2" failures="0" skip="0">
<testcase classname="fibonacci_test.FibonacciTest" name="test" time="0.001"/>
<testcase classname="fibonacci_test2.FibonacciTest" name="test" time="0.001"/>
<testcase classname="fibonacci_test2.FibonacciTest" name="test_invalid_argument" time="0.000"/>
これらを繋ぎ込むことで、テスト結果を確認しながら実装を進めていくことが可能になります。
何をどこまでテストすべきかは、 パッケージソフト開発のテスト体制 の記事を参考にして考えてみましょう。 ソフトウェア・テストPRESS Vol.9 (2009年10月) の原稿だそうです。