Pythonで使えるユニットテスト・フレームワーク「nose」について、情報をまとめてみます。

特徴

「nose」は、Pythonで使えるユニットテスト・フレームワークの一つです。他のフレームワークを使ったことがないので、なんとも言えないのですが...

  • Class継承する必要がなく、シンプルなテストが書ける。
  • 豊富なオプション・ツール類が提供されている。
  • プラグインによる拡張機能がある。

などが、特徴かなと思います。普通に使う分にはシンプルで使い勝手が良いです。

他のフレームワークが気になる方は、Wikipediaを参考にしてみてください。

Install

pipコマンドを使ってインストールします。

$ pip install nose

未確認ですが、pipが使えない環境は、easy_installも使えるみたいです。

$ easy_install nose

初めてのユニットテスト

noseを使ったテストの流れを説明します。

1. 実装(プロダクトコード)

まずは、テスト対象のプロダクトコードを用意しましょう。今回はサンプルとして、指定した数値を加算する関数を用意してみました。

[add.py]

def add(x, y):
    return x + y

2. 実装(テストコード)

上記コードのテストは、以下のように実装することができます。

[test_add.py]

def test_add():
    assert 5 == add(2, 3)

noseでテストを実行させるためには、2つのルールを守る必要があります。

  1. テストファイル名のプレフィックスに、「test_」を付けること。
  2. テスト対象の関数・クラス・メソッドのプレフィックスに「test_」(クラスの場合は「Test」)を付けること。

このルールを守って頂けたら、あとは好きに実装して構いません。今回は、Python標準のassert関数を使っていますが、noseが提供しているツール群を利用することもできます。そちらについては後々説明したいと思います。

また、テストコードはクラスを使うこともできます。上記の「test_add.py」は、以下のように実装することもできます。

class TestClass(object):
    def test_add():
        assert 5 == add(2, 3)

3. テストしてみる。

プロダクトコードとテストコードを用意ができたら、テストを実行してみましょう。テストはシェルから「nosetests」コマンドを実行します。noseは、カレントディレクトリから、「test」が付いているファイルを再帰的に検索し、テストを実行します。従って通常は引数は不要です。

$ nosetests

もちろん、テスト対象を指定することもできます。

$ nosetests test_add.py

コマンドを実行すると、テストの実行結果がコンソールに出力されます。

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

コンソールに出力されている「.」ですが、意味があります。文字の個数はテスト件数に相当し、文字は実行したテストの結果を意味します。出力される文字の種類と意味は、以下のようになります。

  • . ... テストに成功した。
  • F ... テストに失敗した。プロダクトコードに問題あり。
  • E ... テストの実行に失敗した。テストコードに問題あり。

テストに失敗した場合のサンプルは以下のとおりです。コンソールに「F」と失敗した箇所のスタックトレースが出力されることが分かると思います。

[test_add_ng.py]

def test_add():
    assert 6 == add(2, 3)
$ nosetests test_add_ng.py
F
======================================================================
FAIL: test_add_ng.test_add
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/sbkro/.virtualenvs/nose/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/sbkro/tmp/nose/test_add_ng.py", line 9, in test_add
    assert 6 == add(2, 3)
AssertionError

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

テストの実行に失敗した場合のサンプルは以下のとおりです。テスト実行中に、例外が発生した場合に、「E」が表示されます。(例外が発生したことを確認するテストは、assert_raisesメソッドなどを使って検証します。実装方法は、後々説明します。)

[test_add_error.py]

def test_add():
    # テスト実行中に例外が発生した。
    raise Exception()
$ nosetests test_add_error.py
E
======================================================================
ERROR: test_add_error.test_add
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/sbkro/.virtualenvs/nose/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/sbkro/tmp/nose/test_add_error.py", line 10, in test_add
    raise Exception()
Exception

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)

noseの簡単な使い方は以上になります。いかがでしょうか?

まとめ

noseを使うことで、簡単な命名ルールで簡単にテストの作成・実行できることがお分かりになったと思います。次回以降、noseのオプションやツール類について、ご紹介したいと思います。



Comments

comments powered by Disqus