いろんなもの使ってSBM その1 ゼロ機能リリース
setuptoolsレディなプロジェクトを生成する。
paster create wsgibookmark
色々質問されるが、そこは適宜答える(全部空でもOK)
$ cd wsgibookmark $ ls setup.cfg wsgibookmark setup.py wsgibookmark.egg-info
生成されるのはこんな感じ
このうちwsgibookmark.egg-infoは setup.py egg_info で生成できる。
SCMに入れたくないので一旦削除
$ rm -rf wsgibookmark.egg-info/
SCMに登録する。ここではMercurial HG を使ってるが、お好きなように。
$ hg init $ hg commit -A -m 'start wsgibookmark'
登録したら作業リポジトリを作成
$ cd .. $ hg clone wsgibookmark wsgibookmark-work $ cd wsgibookmark-work
テスト環境を作成する。
twill, py.testを利用する。
twillはhttpリクエストを元にした機能テスト
py.testはユニットテストに使用する
$ mkdir -p tests
最初のテストは、単にトップページにアクセスして、bookmarkと表示されることを確認する。
# -*- coding:utf-8 -*- import os import twill from twill.commands import * from paste.deploy.loadwsgi import loadapp def setup_module(mod): def create_app(): relative = os.path.join(os.path.dirname(__file__), os.pardir) return loadapp("config:test.cfg", relative_to=relative) twill.add_wsgi_intercept('localhost', 80, create_app) def test_top(): go("http://localhost") assert show() == 'bookmark'
setup_moduleはテストモジュール内のテストが実行される前に呼び出される。
この中ではlocalhostの80番ポートにこれからテストするアプリケーションを疑似的にマッピングしている。
これによってtwillコマンド(上の例にあるgoやshow)がlocalhost:80にアクセスしようとすると、マッピングされたアプリケーションにリクエストが転送される。
実際にアプリケーションがlocalhost:80で動くわけではない。
アプリケーションをロードするには、paste.deploy.loadwsgi.loadappを使っている。
loadappにはPasteDeployの設定ファイルを引数とするが、まだその設定ファイルを書いていない。
当然テストは失敗するだろう。
$ touch tests/__init__.py $ py.test inserting into sys.path: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/py-0.9.0-py2.5.egg ============================= test process starts ============================== executable: /Library/Frameworks/Python.framework/Versions/2.5/Resources/Python.app/Contents/MacOS/Python (2.5.1-final-0) using py lib: /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/py-0.9.0-py2.5.egg/py <rev unknown> tests/test_application.py[1] F ... > OSError: File /Users/aodag/wsgibookmark-work/tests/../test.cfg not found
py.testコマンドは実行したディレクトリ以下にある、test_で始まる名前のpythonモジュールをテストモジュールとして実行する。
予想通りテストは失敗し、その原因もtest.cfgファイルが見つからないことになっている。
設定ファイルを作ろう。
名前はもちろんtest.cfgで置く場所はtestsの1つ上のディレクトリ。つまりプロジェクトディレクトリの直下だね。
[app:main] paste.app_factory = wsgibookmark:factory [server:main] use = egg:PasteScript#wsgiutils port = 8080
PasteDeployの設定では主に二種類のものを設定する。
アプリケーションとサーバーだ。
アプリケーションはこれから僕らが作るもの。
サーバーはこれを動かす土台だ。
このサーバーはscgiやfcgiのようにhttpdのバックエンドとして動かすものもあればスタンドアローンで使える手軽なものまである。
開発用にはスタンドアローンなものがよいだろう。
PasteScriptのentry_pointにwsgiutilsのスタンドアローンサーバーが設定されているので、それを使う。
アプリケーションには、すでにインストールされているeggからentry_point経由で引っ張ることもできるが、ここはこれから作るものを指定する。
この場合は、ファクトリを設定する。
アプリケーションファクトリの設定は、paste.app_factoryをキーにする。
さて、まだファクトリを書いていないのだから、テストはまだ失敗する。
失敗することを確認したら、ファクトリを書こう。
wsgibookmark:factoryはfrom wsgibookmark import factory で取得できるオブジェクトと考えればいい。
今回の構成では、wsgibookmark/__init__.py 内で factory を定義すればいい。
def app(envrion, start_response): start_response("200 OK", [("Content-type", "text/html")]) return [""] def factory(global_conf, **local_conf): return app
テスト結果
def test_top(): go("http://localhost/") E assert show() == 'bookmark' > assert '' == 'bookmark' + where '' = show()
もちろんまだ、空文字を返しているから上のようなエラーになる。
app関数の戻り値を["bookmark"]にして再度テストを実行してみよう。
tests/test_application.py[1] .
テストが通った!
ひとまずこれをコミットする
$ hg add tests/test_application.py test.cfg $ hg commit -m 'bookmark application'
実際に動くものを確認してみよう。
$ paster serve test.cfg
アプリケーションを起動できたらブラウザでhttp://localhost:8080にアクセスする。
bookmarkの文字が確認できるはずだ。
参考リンク
- http://codespeak.net/py/dist/test.html py.test
- http://pythonpaste.org Paste, PasteDeploy, PasteScript
- http://twill.idyll.org/ twill