mockを使用してpythonアプリケーションをテストする
最近nosetestsとmock 1をbottleに適用してテストしたところ、nosetestsを使用する上で注意すべき点がいくつか見つかりました.
1 patch method of module
patchはmoduleをインポートするmethodである、methodはすでにターゲットファイルにインポートされているため、元のmoduleではなくpatchターゲットファイルのこの方法が必要である.
2 patch decorator
Scenario:bottleのviewsはdecoratorで定義されています.つまり、bottleのactionをテストするとき、このactionはviewsに包まれています.returnのdictはbottleのviews関数renderによってhtmlに戻されます.viewsが返すhtmlをテストする必要はありません.returnのdictが正しいかどうかをテストするだけです.
この状況はmockのpatchにぴったりだ. patch bottle.view は、神馬がやっていない関数 を返します.このpatch を起動テストが必要なアプリケーションコード をインポート
ここのpatchはimportあなたのアプリケーションの前になければなりません.例えば、私のアプリケーションは
完全なプロセスはこうです
3 mock module that may not exist
Scenario:いくつかのスプーン付きプロファイル(google api keyなど)はgithub publicにアップロードされることを望んでいませんが、テストにはこれらのファイルを導入する必要があります.(後に、local configを使用してスプーンを保存するよりelegantの解決策を発見しました).スプーン付きプロファイルをconfig.pyと仮定すると、ターゲットファイルはwsgi.pyです.
これではpatchでは何の役にも立たない.patchの場合、まずターゲットファイルを導入しなければならないので、ターゲットファイルのimport configが先に異常を投げ出すからだ.
では、wsgiを導入する前にpatch configについて、システムのconfigモジュールをmockのconfigに等しくする必要があります.これでwsgiを導入しても問題はありません.
4 travis ciによる継続的な統合
継続的な統合の最も簡単な構成はもちろんTravis CIです.構成ファイル
5 local configを使用してスプーンを保存
この方法はdjango.から突然djangoのsettings.pyの最後の数行を思い出した.
Footnotes:
1
: mock is now part of the python 3 now. Whee…..
[](http://oyanglul.us/#/gist/9866674/How to use Mock testing Python)
1 patch method of module
patchはmoduleをインポートするmethodである、methodはすでにターゲットファイルにインポートされているため、元のmoduleではなくpatchターゲットファイルのこの方法が必要である.
# wsgi.py
from db import get_db
def insert_something():
get_db().insert(something)
# test.py
import wsgi
# @patch('db.get_db') # this won't work
@patch('wsgi.get_db') # should patch wsgi
def test_insert(mock_get_db):
mock_get_db.return_value = Database()
...
2 patch decorator
Scenario:bottleのviewsはdecoratorで定義されています.つまり、bottleのactionをテストするとき、このactionはviewsに包まれています.returnのdictはbottleのviews関数renderによってhtmlに戻されます.viewsが返すhtmlをテストする必要はありません.returnのdictが正しいかどうかをテストするだけです.
この状況はmockのpatchにぴったりだ.
ここのpatchはimportあなたのアプリケーションの前になければなりません.例えば、私のアプリケーションは
wsgi.py
です.完全なプロセスはこうです
from mock import patch, Mock
import bottle
v = patch("bottle.view",return_value = lambda x : x)
v.start() ** local config
import wsgi
3 mock module that may not exist
Scenario:いくつかのスプーン付きプロファイル(google api keyなど)はgithub publicにアップロードされることを望んでいませんが、テストにはこれらのファイルを導入する必要があります.(後に、local configを使用してスプーンを保存するよりelegantの解決策を発見しました).スプーン付きプロファイルをconfig.pyと仮定すると、ターゲットファイルはwsgi.pyです.
これではpatchでは何の役にも立たない.patchの場合、まずターゲットファイルを導入しなければならないので、ターゲットファイルのimport configが先に異常を投げ出すからだ.
では、wsgiを導入する前にpatch configについて、システムのconfigモジュールをmockのconfigに等しくする必要があります.これでwsgiを導入しても問題はありません.
import sys
config_mock = Mock(spec=['config'])
config_mock.__name__ = 'config'
sys.modules['config'] = config_mock
4 travis ciによる継続的な統合
継続的な統合の最も簡単な構成はもちろんTravis CIです.構成ファイル
.travis.yml
を追加するだけで、4つのものを定義するだけです.次は私の.travis.yml
です.language: python
python:
- "2.7" # version
install: "pip install -r requirements.txt --use-mirrors" # requirements
script: nosetests # test or build command
5 local configを使用してスプーンを保存
この方法はdjango.から突然djangoのsettings.pyの最後の数行を思い出した.
try:
from local_settings import *
except:
pass
local_settings
のすべての設定から導入することを意味するので、本物のスプーン付き本物の配置をlocal_settings
に書くことができる.Footnotes:
1
: mock is now part of the python 3 now. Whee…..
[](http://oyanglul.us/#/gist/9866674/How to use Mock testing Python)