AppEngine(Python)のテスト環境を整える

前回までに引き続き、今度はAppEngineのテスト環境を整えてみたいと思います。

noseを導入する

nose を使うことで、

  • unittest.TestCaseを継承しなくてもテストコード扱いしてくれる
  • 自分でテストスイートを作らなくてもよい

といったメリットがあるようなので導入してみます。

pbp.recipe.noserunner というbuildout用のレシピが公開されているので、buildout.cfgにtestというパーツを追加してみました。

[buildout]
parts =
    gae_sdk
    gae_tools
    app_lib
    test
(中略)
[test]
recipe = pbp.recipe.noserunner
extra-paths = ${gae_tools:extra-paths}
working-directory = ${buildout:directory}/app

bin/buildoutを再度実行すると、bin/testというスクリプトが追加されるので、ためしに以下のコードを追加してテストを実行してみました。

app/test/lib/foo_test.py

import unittest
from foo import Foo

class TestFoo(unittest.TestCase):
    def test_foo(self):
        f = Foo()
        self.assertEqual('foo', f.foo())

app/lib/foo.py

class Foo:
    def foo(self):
        return 'foo'

うまく動いたようです。

$ bin/test
.
----------------------------------------------------------------------
Ran 1 test in 0.013s

OK

NoseGAEを使う

noseにはAppEngine用の NoseGAE というプラグインがあるので合わせて導入してみます。これは主に、

  • 機能テストを書ける
  • Datastoreなどを利用したテストを書ける(AppEngineのSDKをロードパスに追加してくれる)
  • AppEngine上で利用できないはずのライブラリ(socketなど)を無効にしてくれる(sandbox化)

といったメリットがあるようです。
buildout.cfgのtestパーツを以下のように修正してみました。(eggs, defaultsの指定を追加)

[test]
recipe = pbp.recipe.noserunner
extra-paths = ${gae_tools:extra-paths}
working-directory = ${buildout:directory}/app
eggs =
    distribute
    nosegae
defaults =
    --with-gae
    --gae-lib-root
    ${buildout:parts-directory}/google_appengine
  • なるべくbin/dev_appserverと同じ参照にしたいと考え、eggsの指定は最低限にしてみました。distributeを指定しないとNoseGAEプラグインが有効にならなかったのですが、これでよいのかちょっと自信がないです。
  • --gae-lib-rootオプションは指定しないと/usr/local/google_appengineを参照してしまうので、buildoutで用意したSDKのパスを指定しています。
  • noseの--whereオプションを使う場合は、--gae-applicationオプションでapp.yamlのあるディレクトリを指定する必要があるようです。(詳細はNoseGAEのソースを参照)

これでDatastoreなどに依存したコードのテストも実行できると思います。buildoutを使えばNoseGAEを使わなくてもロードパスの調整はできるので、sandbox化以外のメリットをあまり実感できていませんが…。
あと今後はVersion 1.4.3のSDKから追加されたTestBedを使っていきたいと思っています。( 参照 )

関連エントリ

blog comments powered by Disqus