Ginkgoでテストを書く
みんな大好きgeventをベースにした、daemonを書くためのフレームワークGinkgo(repo)でテストを書く方法について。
Ginkgoについての軽い説明
0.5.0devのドキュメントを読めばわかるんですが、Ginkgo(ギンコ?)は纏まった1つの機能を Service と呼び、Service の中には複数の子Serviceを持てるようになっています。
Service はこんな感じで書きます。
# 1秒毎にコンソールに Hello World と表示し続けるサービス # http://ginkgo.readthedocs.org/en/latest/user/quickstart.html#hello-world-service からのコピペです from ginkgo import Service class HelloWorld(Service): def do_start(self): self.spawn(self.hello_forever) def hello_forever(self): while True: print "Hello World" self.async.sleep(1)
こいつを実行するには、Ginkgoをインストールすると生成されるコマンド ginkgo または ginkgoctl を使います。(上記のコードを hello.py とする)
$ ginkgo hello.HelloWorld
設定ファイル
daemonを作るフレームワークなので、設定ファイルを扱う仕組みが既にあります。
詳しくはドキュメントを読んでいただくとして、下記のコードをみてください。
# service.py from ginkgo import Service, Setting class HelloWorld(Service): message = Setting("message", default="Hello World", help="Message to print out while running") def do_start(self): self.spawn(self.message_forever) def message_forever(self): while True: print self.get_message() self.async.sleep(1) def get_message(self): return self.message + '!'
# 設定ファイル(といいつつ普通のPythonコード) # service.conf.py message = "Services all the way down." service = "service.HelloWorld"
以下のコマンドで実行
$ ginkgoctl service.conf.py start
上記のコード中の Setting は(ドキュメントに書かれていませんが)シングルトンになっていて、Service が複数あったとしても Setting の第1引数が同じであれば全ての Service (子Serviceも含む)から設定値が参照できます。
で、実は Setting は ginkgo.settings から設定値を取ってくるためのラッパーなので、設定ファイルを介さずに設定値を弄りたいときは ginkgo.settings をつつけばどうとでもなるというわけです。
ここ重要なんで覚えといてください。
テストを書く
ginkgo.settings を直接弄ると「設定ファイルから設定値を読む」処理の下準備をしなくて済むのでとても楽です。
# service_test.py from unittest import TestCase from ginkgo import settings from service import HelloWorld class HelloWorldTest(TestCase): def tearDown(self): # .load() で設定値をデフォルトで上書き # 与えられた辞書のkeyをもとに settings を更新するので # 空の辞書を与えてまっさらに、とはいかない settings.load({'message': "Hello World"}) def test_message(self): # 設定値をセット settings.load({'message': 'spam'}) service = HelloWorld() assert service.get_message() == 'spam!'
こんな感じで。