GAE Python環境でテストどうしよう、という話でGAEUnitを試してみた。簡単に方法と特徴をまとめておく。
使いかた
- gaeunit.pyをダウンロードして、他のコントローラと同じ場所に置く
- app.yamlに設定を追記する
- 内容はGAEUnitのページの先頭に書いてあるまんま
- HTTPでアクセスできるようにする
- dev環境ならdev_appserver.pyを起動する
- production環境ならappcfg.py updateする
- ブラウザで /test を開く
ブラウザでページを開くと作成済みのテストが全部実行される。実行対象はgaeunit.py内に書かれている _LOCAL_TEST_DIR で指定するようだ。(デフォルトは /test)。テストのうち、どれを実行するとか選ぶような悠長なことはない。すべて実行される。
特徴
作りとしては各テストごとに対応するHTTPリクエストがある(/test/run)、が、ブラウザで /test を開いた瞬間にAjaxで各テスト実行用のリクエストが行われてしまうので、選ぶ余地は実質的には無いと思っていい。個別実行用のUI自体はHTML/JSで簡単に書けるだろうけど、あまり意味もなさそう。
テストの実行時、DatastoreServiceについては DatastoreFileStub が使用される。これはdev/productionにかかわらず。(他のスタブは各環境のものがそのまま使われる。)
ということでGAEUnitをproduction環境にアップロードしても、productionのDatastoreで実行はできない。
※問題のコード (from gaeunit.py)
def _run_test_suite(runner, suite): """Run the test suite. Preserve the current development apiproxy, create a new apiproxy and replace the datastore with a temporary one that will be used for this test suite, run the test suite, and restore the development apiproxy. This isolates the test datastore from the development datastore. """ original_apiproxy = apiproxy_stub_map.apiproxy try: apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap() temp_stub = datastore_file_stub.DatastoreFileStub('GAEUnitDataStore', None, None, trusted=True) apiproxy_stub_map.apiproxy.RegisterStub('datastore', temp_stub) # Allow the other services to be used as-is for tests. for name in ['user', 'urlfetch', 'mail', 'memcache', 'images']: apiproxy_stub_map.apiproxy.RegisterStub(name, original_apiproxy.GetStub(name)) runner.run(suite) finally: apiproxy_stub_map.apiproxy = original_apiproxy