Amazon

ラベル nose の投稿を表示しています。 すべての投稿を表示
ラベル nose の投稿を表示しています。 すべての投稿を表示

2011年9月3日土曜日

Pythonでテスト駆動開発2 -Aptanaからnoseの実行-

前回noseを使って、Pythonでテストを実行する方法について書いた。
今回はAptana(Eclipse)からPythonのテストフレームワークのnoseを使用する方法をまとめます。

テストするクラスとテストコードは前回のtest1.py, test2.py

test1.py, test2.pyでは使用していないけど、
テストコードで以下の一文があると、まずライブラリが見つからないとAptana(Eclipse)から怒られる。
from nose.tools import ok_, eq_

ということで解決策
1. プロジェクトを右クリックしてプロパティ
2. PyDev - PYTHONPATHにnoseのライブラリフォルダを追加
 (C:\Python27\Lib\site-packages\nose-1.1.2-py2.7.egg)

テストの実行は
test2.pyの最後に
if __name__ == '__main__':
    import nose
    nose.main()
の記述を入れると、pythonの実行ファイルと認識されて、Eclipseの実行設定ファイルで読み込めるようになる。

ちなみに実行設定ファイルは以下の通り。




で、上記を実行すると
Failure: ImportError (No module named testdata) ... ERROR
Failure: ImportError (No module named sancho.unittest) ... ERROR
Failure: ImportError (No module named sancho.unittest) ... ERROR
Failure: ImportError (No module named sancho.unittest) ... ERROR
Failure: ImportError (No module named sancho.unittest) ... ERROR
Failure: ImportError (No module named sancho.unittest) ... ERROR
Failure: ImportError (No module named sancho.unittest) ... ERROR
Failure: ImportError (cannot import name AES) ... ERROR
Failure: ImportError (No module named testdata) ... ERROR
という結果になる。

このプロジェクト内のテスト(class Testxxx)を全部実行するため、 本来テストしたいもの以外も実行されてしまっている。

ということで、必要なテストだけを実行する場合は--tests=NAMEオプションを付けて実行する。
通常はnose.main()にargs=["-v","--name=tests2.py"] を渡して
test.py
if __name__ == '__main__':
    import nose
    nose.main(args=["-v","--name=tests2.py"] )
とするのが一般的のようだけど、何故か引数が有効にならない。
Aptana(Eclipse)を使用する場合はmainへの引数は実行設定ファイルで設定するようです。



で実行するとverboseモードになって(test.xxx ... okみたいな)テスト結果が表示される。

test2.TestDollar.Multiplicaton_test ... ok

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

OK


○注意点
class名はTestxxxとTestで始めること
メソッド名はyyy_testとすること

2011年9月1日木曜日

Pythonでテスト駆動開発1

Pythonでテスト駆動開発を行うためのツールとしてunittestとnoseがある。参考はこちら
unittestでは必要なクラスを継承するなど、いくつかの決まりごとがあるが、noseでは正規表現 "(?:^|[b_.-])[Tt]est" にマッチしたクラス・関数が実行されるようになっているため、ルールがシンプル。

noseのインストール
% easy_install nose
 
○テスト実行時
テストの実行は次の2種類があります。
  1. nosetests コマンドでテスト対象のファイルやディレクトリを指定
  2. テストスクリプト内でテストを実行
(1) の場合は、nosetests の引数にテストファイルを指定、あるいは -w オプションでテストファイルを含んだディレクトリを指定することでテスト実行します。
(2)の場合は、テストプログラム内で nose.main 関数を呼び出すようにします。
def test_compare():
    assert 1==1
if __name__ == '__main__':
    import nose
    nose.main()


テストクラスが入っているディレクトリ内で 
% nosetests 
 
サンプルクラス(test1.py)
#-*- coding: utf-8 -*-

class Dollar():

    def __init__(self, amount=0):
	self.amount = amount

    def times(self, multiplier):
	self.amount *= multiplier
テストコード(test2.py)
#-*- coding: utf-8 -*-

from test1 import Dollar
from nose.tools import *

class TestDollar():

    def testMultiplicaton(self):
        five = Dollar(5)
        five.times(3)
        eq_(15, five.amount)
成功すると
---------------------
Ran 1 test in 0.047s

OK
失敗すると
======================================================================
FAIL: test2.TestDollar.testMultiplicaton
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\nose-1.1.2-py2.7.egg\nose\case.py", line 1
97, in runTest
    self.test(*self.arg)
  File "C:\temp\test2.py", line 11, in testMultiplicaton
    eq_(10, five.amount)
  File "C:\Python27\lib\site-packages\nose-1.1.2-py2.7.egg\nose\tools.py", line
31, in eq_
    assert a == b, msg or "%r != %r" % (a, b)
AssertionError: 10 != 15

----------------------------------------------------------------------
Ran 1 test in 0.562s

FAILED (failures=1)
○オプション

verbose モード

「-v」 オプションを有効にすると、verbose モードでテストが実行されます。-vvv のように v を重ねると、より verbose なメッセージが表示されます。

pdb 対応


「--pdb」 オプションを有効にすると、テストプログラムで例外が起きると同時に、pdb が起動し、デバッグモードに入ります。

「--pdb-failures」オプションを有効にすると、テストプログラムでテストが失敗すると同時に、pdb が起動し、デバッグモードに入ります。

パターンマッチ


「-i 正規表現パターン」オプションを有効にすると、正規表現にマッチしたファイルのみがテスト実行されます。

「-e 正規表現パターン」オプションを有効にすると、逆に正規表現にマッチしたファイルは実行されなくなります。


○さらに詳しく理解するには
nose まとめ 1

Amazon3