テスト用のデータをつくる

Google App Engine で開発。第九弾。

GAE python27 です。

できる限り追加パッケージを導入しないでテスト用データをつくる方法を考えます。もっと良い方法があったら教えてください。

dev_appserver.py を実行して開発サーバを動作させます。この際、下記をコマンド引数に指定してデータストアの保存先を指定します。Eclipse での設定方法のため ${project_loc:/project_name} を使用しています。

--datastore_path=${project_loc:/project_name}/data/datastore.txt


既に設定してある bulkloader.yaml (http://d.hatena.ne.jp/nosix/20120905/1346849008 参照) を使って開発サーバにアップロードします。

$ cd data
$ ls .
SeedKind.csv
bulkloader.yaml
$ appcfg.py upload_data --config_file=bulkloader.yaml --url=http://localhost:8080/_ah/remote_api --kind=SeedKind --filename=SeedKind.csv


SeedKind.csv

note,link,class,id,name
,,"[u'SeedKind', u'Family']",1,ヤシ
,,"[u'SeedKind', u'Family']",2,イネ
,,"[u'SeedKind', u'Family']",3,アブラナ
,,"[u'SeedKind', u'Family']",4,マメ
,,"[u'SeedKind', u'Family']",5,オトギリソウ
,,"[u'SeedKind', u'Family']",6,セリ
,,"[u'SeedKind', u'Family']",7,シソ
,,"[u'SeedKind', u'Family']",8,キク


すると、data/datastore.txt にデータが保存されます。

data/datastore.txt のデータをテストで使ってみます。ディレクトリ構成の一部を示します。

app_root
  app.yaml
  main.py
  tools
    test_.py ... テスト用のユーティリティ
  category
    tests.py ... テストスイート


main.py

import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

def app_root():
    return os.path.dirname(__file__)

def app_config():
    from google.appengine.tools import dev_appserver
    config, _, _ = dev_appserver.LoadAppConfig(app_root(), {})
    return config

def main():
    from django.core.handlers.wsgi import WSGIHandler
    application = WSGIHandler()
    from google.appengine.ext.webapp.util import run_wsgi_app
    run_wsgi_app(application)

if __name__ == '__main__':
    main()


tools/test_.py

import main

APP_CONFIG = main.app_config()
APP_ROOT = main.app_root()
APP_ID = 'dev~' + APP_CONFIG.application

def run_server(**option):
    from google.appengine.tools import dev_appserver
    from google.appengine.tools import dev_appserver_main
    option_dict = dev_appserver_main.DEFAULT_ARGS.copy()
    option_dict.update(option)
    dev_appserver.SetupStubs(APP_ID, **option_dict)

def register_stub(**stub_dict):
    from google.appengine.api import apiproxy_stub_map
    apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
    for key, stub in stub_dict.items():
        apiproxy_stub_map.apiproxy.RegisterStub(key, stub)

def datastore_stub(filename):
    import os
    file_path = os.path.join(APP_ROOT, filename)
    from google.appengine.api.datastore_file_stub import DatastoreFileStub
    return DatastoreFileStub(APP_ID, file_path, save_changes=False)

def init_stub(datastore):
    from google.appengine import api
    register_stub(
        datastore_v3=datastore,
        user=api.user_service_stub.UserServiceStub(),
        urlfetch=api.urlfetch_stub.URLFetchServiceStub(),
        mail=api.mail_stub.MailServiceStub()
    )


APP_ID : data/datastore.txt をみると保存したときの application_id が確認できます。application_id には dev~ が付いているため、このデータを取り出すためには application_id に dev~ を付ける必要があります。

DatastoreFileStub の save_changes : エンティティを保存した際にファイルに保存しないようにします。テストケース実行中に data/datastore.txt の内容が変更されないようにするためです。

テストスイートで tools.test を使用します。

category/tests.py

from tools import test_ as test

datastore = test.datastore_stub('../data/datastore.txt')

def setup():
    test.run_server()
    datastore.Read()
    test.init_stub(datastore)

def teardown():
    #datastore.Write()
    pass


試行中の方法なので何か問題があるかもしれませんが、ひとまず datastore.txt は読み込まれました。