: O. Yuanying

Pythonでスパムフィルタを書く/テスト環境のセットアップ

唐突にPythonを勉強したくなったので、 とりあえず勉強がてらPaul GrahamのA Plan for Spamを参考に、 Pythonでスパムフィルタを書いてみる。

Pythonの知識と言えばtracを使っていて、そのプラグインをちょこっと書いたことがあるくらいなので、 ほとんど右も左もわからない状態なのであまり役には立たないログになること間違いなし。

テスト環境の選定

とりあえずユニットテストができると良いなと思ったので、 「python テスト」 でぐぐる。

nose: a discovery-based unittest extension」 とかいうテスティングフレームワークがみつかる。これに決定。

もちろん予備知識なんて無いからこの選択が正しかったのか確信は持てません!

判断基準

  • PythonのxUnit的扱いっぽいpy.testの後発っぽい
  • 後発ってことはきっと色々改善されてるに違いない
  • 色々って何だろう

テストしてみる


#!/usr/bin/env python
# coding:utf-8

def test_compare():
    assert 1==1

とかいうファイルをTestTest.pyという名前で保存してみる。

[yuanying@Magnus] ~/Projects/python
$ nosetests test/TestTest.py
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

おk。

nodetestsコマンドを使わないでpythonからいきなり実行するには、


#!/usr/bin/env python
# coding:utf-8
import nose

def test_compare():
    assert 1==1

if __name__ == '__main__':
    nose.main()

って書けば良いみたい。

[yuanying@Magnus] ~/Projects/python
$ python2.5 test/TestTest.py
.
----------------------------------------------------------------------
Ran 1 test in 0.025s

OK

おk。

プロジェクト作成

それじゃースパムフィルタプロジェクトを作成してみようか!

[yuanying@Magnus] ~/Projects/python
$ mkdir pgspam-project
[yuanying@Magnus] ~/Projects/python
$ mkdir pgspam-project/pgspam
[yuanying@Magnus] ~/Projects/python
$ mkdir pgspam-project/test
...

SpamFilterProject1.png

こんな感じ。

とりあえずよくわかんないけど、 module名がpgspamでユニットテストコードをtestフォルダに保存するpgspam-projectを作成した!

テストコードは以下のコマンドでプロジェクトのルートディレクトリで実行する。

[yuanying@Magnus] ~/Projects/python/pgspam-project
$ find . -name "*Test.py" -exec "/opt/local/bin/python2.5" '{}' \;

pgspam.testモジュールを作成して、


#!/usr/bin/env python
# coding:utf-8

def fname():
    """docstring for fname"""
    print 'test'

test/TestTest.pyを書いて、


import nose
import pgspam.test

def test_compare():
    assert 1==1
    pgspam.test.fname()

if __name__ == '__main__':
    nose.main()

早速このモジュールをテストしてみる。

[yuanying@Magnus] ~/Projects/python/pgspam-project
$ find . -name "*Test.py" -exec "/opt/local/bin/python2.5" '{}' \;
Traceback (most recent call last):
  File "./test/TestTest.py", line 11, in <module>
    import pgspam.test
ImportError: No module named pgspam.test

あれ、失敗。pgspam.testモジュールなんて無いって言われた。

ああ、そうか、ロードパスが通ってないんだなってことで、 pythonでロードパスを通す方法をぐぐる。

結局テストコードはこんな感じに。


#!/usr/bin/env python
# coding:utf-8
import sys, os
script_dir = os.path.dirname(os.path.abspath(__file__))
base_dir = script_dir + os.sep + '..'
if not base_dir in sys.path:
    sys.path.insert(0, base_dir)

import nose
import pgspam.test

def test_compare():
    assert 1==1
    pgspam.test.fname()

if __name__ == '__main__':
    nose.main()

毎回プロジェクトのルートにロードパスを通すのめんどいな…。