たごもりすメモ

コードとかその他の話とか。

GAEUnit試してみた

GAE Python環境でテストどうしよう、という話でGAEUnitを試してみた。簡単に方法と特徴をまとめておく。

使いかた

  1. gaeunit.pyをダウンロードして、他のコントローラと同じ場所に置く
  2. app.yamlに設定を追記する
    • 内容はGAEUnitのページの先頭に書いてあるまんま
  3. HTTPでアクセスできるようにする
    • dev環境ならdev_appserver.pyを起動する
    • production環境ならappcfg.py updateする
  4. ブラウザで /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