メニュー

2013年10月16日

Google App Engine 1.8.6 で Go言語の単体テストがサポート

Google App Engine 1.8.6 がリリースされました。

そしてついに、Go版で単体テスト用のパッケージ appengine/aetest が追加されました!

AppEngineのローカルでの開発サーバはPythonで実装されており、Pythonの開発サーバがGoアプリを呼び出すように動作しています。この仕組み上、Goの単体テストからAppEngineのAPIを呼び出すことが困難でした。

新たに追加された appengine/aetest を使うと、以下のように単体テストを書くことができます。
package foo_test
import (
    "testing"
    "appengine/memcache"
    "appengine/aetest"
)
func TestFoo(t *testing.T) {
    c, err := aetest.NewContext(nil)
    if err != nil {
        t.Fatal(err)
    }
    defer c.Close()
    it := &memcache.Item{
        Key:   "some-key",
        Value: []byte("some-value"),
    }
    err = memcache.Set(c, it)
    if err != nil {
        t.Fatalf("Set err: %v", err)
    }
    it, err = memcache.Get(c, "some-key")
    if err != nil {
        t.Fatalf("Get err: %v; want no error", err)
    }
    if g, w := string(it.Value), "some-value" ; g != w {
        t.Errorf("retrieved Item.Value = %q, want %q", g, w)
    }
}
この例では、memcache APIを使ったテストをしています。aetest.NewContext が appengine.Context インタフェースを返すので、これを使って各種APIを呼び出すことが出来ます。 

単体テストの実行には go test ではなくSDKに同梱されている goapp コマンドを使います。
export APPENGINE_API_SERVER=/path/to/go_appengine/api_server.py
goapp test
環境変数 APPENGINE_API_SERVER は、SDKをインストールした場所に応じて値を設定します。aetest は裏でPythonのAPI Serverを起動し、そこと通信することでAPIを動かしていますので、そのためにSDKの場所を設定する必要があります。

※aetest.NewContextするたびに、データストア等は新しい領域が使われるようで、テストをまたがってデータが永続化されてしまうことは起きないようです。
※NewContextはテストケースごとに書きますが、中ではPythonのプロセスを起動しているので、やや重い気がします。ここは今後の改善に期待したいところ。

Enjoy Testing!