Google App Engine (以下 GAE)アプリケーションの、Web API 部分のテストを自動化するために、webtest というツールを導入してみた。
webtest は WSGI アプリケーションをテストするための便利ツール。WSGI アプリケーションにダミーのリクエストを簡単に送る事ができる。webtest は easy_install を使ってインストール。
GAE アプリケーションは、中で Datastore API や Memcached API を使っている場合がほとんど。そのため、テストではスタブを登録する必要がある。以前紹介した GAETestBase を継承してテストクラスを作るといい。
webtest を使ったテストコードのサンプルがこちら。パスの設定と GAETestBase クラスの定義は、別ファイルに書いて import した方が、後々使い回せていいかも。
#!/usr/bin/env python #encoding: utf-8 """ テストの下準備 GAE SDK のパスを設定したり、スタブを登録したりする """ import os import sys GAE_HOME = 'C:/google_appengine' PROJECT_HOME = os.path.join(GAE_HOME, 'apps', 'greeting') EXTRA_PATHS = [ GAE_HOME, PROJECT_HOME, os.path.join(GAE_HOME, 'google', 'appengine', 'api'), os.path.join(GAE_HOME, 'google', 'appengine', 'ext'), os.path.join(GAE_HOME, 'lib', 'yaml', 'lib'), os.path.join(GAE_HOME, 'lib', 'webob'), os.path.join(GAE_HOME, 'lib', 'django'), ] sys.path = EXTRA_PATHS + sys.path import unittest from google.appengine.api import apiproxy_stub_map from google.appengine.api import datastore_file_stub from google.appengine.api import mail_stub from google.appengine.api import urlfetch_stub from google.appengine.api import user_service_stub from google.appengine.api import users from google.appengine.ext import db APP_ID = u"test_id" AUTH_DOMAIN = "gmail.com" LOGGED_IN_USER = "test@example.com" class GAETestBase(unittest.TestCase): def setUp(self): # Regist API Proxy apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap() # Regist Datastore stub stub = datastore_file_stub.DatastoreFileStub(APP_ID, '/dev/null', '/dev/null') apiproxy_stub_map.apiproxy.RegisterStub("datastore_v3", stub) os.environ["APPLICATION_ID"] = APP_ID # Regist UserService stub apiproxy_stub_map.apiproxy.RegisterStub("user", user_service_stub.UserServiceStub()) os.environ["AUTH_DOMAIN"] = AUTH_DOMAIN os.environ["USER_EMAIL"] = LOGGED_IN_USER # Regist urlfetch stub apiproxy_stub_map.apiproxy.RegisterStub('urlfetch', urlfetch_stub.URLFetchServiceStub()) # Regist MailService stub apiproxy_stub_map.apiproxy.RegisterStub('mail', mail_stub.MailServiceStub()) """ webtest を使ったテストコードはここから """ from google.appengine.ext import webapp from google.appengine.ext.webapp import util import webtest # テスト対象のクラス class GreetingHandler(webapp.RequestHandler): def get(self): self.response.out.write("Hello") def post(self): name = self.request.get("name", None) self.response.out.write("Hello, %s" % name) # webtest を使ってテスト用の WSGI アプリを作成 # 作成したアプリを使ってダミーのリクエストを送信する app = webtest.TestApp(webapp.WSGIApplication([ ('/hello', GreetingHandler), ], debug=True)) # スタブを使うかもしれないので GAETestBase を継承 class GreetingHandlerTest(GAETestBase): def test_get(self): resp = app.get('/hello') self.assertEqual('200 OK', resp.status) self.assertEqual('Hello', resp.body) def test_post(self): resp = app.post('/hello', { "name": "Keima" }) self.assertEqual('Hello, Keima', resp.body) if __name__ == '__main__': unittest.main()