動機
Infratasterは素晴らしいGemで、インフラの振る舞いをコードで表現できることはこの上なくありがたい。ただ、使っていると不便に感じるところもいくつかある。
- RSpecにロックインされる
- RSpecの大量に存在するマッチャAPIで消耗する
- RSpec2からRSpec3で構文が変わって非本質的な部分で消耗する
- RSpec上で併用することの多いServerspecとコンテクストが混ざる
- RSpecでは待ち合わせの概念が入ると途端にコードがダサくなる
最後の「待ち合わせ」だけ補足すると、これはWebSocketなどの通信が確立することを確かめたい場合が例としてあげられる。infrataster-plugin-socket.ioを作った際、通信が確立できることを確かめるのに、こういうダサいコードを書くことになった。
タイムアウトの概念が存在して、マッチャAPIがシンプルで、それでいてdescribe
, context
, it
の表現力を備えている代替品が欲しいと思ったら、身近にあるではないか。mocha, power-assertと組み合わせて同じようなことができればよいのではと考えた。
ので作った。
TasteSpoonの使い方
インストール
TasteSpoonはすでにNPMにて公開されているので、npm install
コマンドから直接インストールできる。テスト実行のために必要なmocha, power-assert, さらにES2015で書くのでespower-babelを一緒にインストールする。
$ npm install tastespoon mocha power-assert espower-babel --save-dev
mocha, power-assertを使うのが嫌でも、Jasmineやchaiなど他のNodeベースのテストツールと組み合わせられるはずなので、ベストと思う組み合わせで使ってほしい。
使い方
ここからは、Infratasterでリバースプロキシのテストをする - クックパッド開発者ブログあたりに目を通していて、Infratasterで何ができるかを把握していること前提で書く。
まずはテスト対象となるサーバを用意しよう。今回はTasteSpoonに最初から備わっているHTTPのテストを考える。とりあえずTasteSpoon.http
の動作を見るということで、ローカルにサーバを立ち上げてそこに接続するテストを書いてみよう。
$ python -m SimpleHTTPServer 8080
import TasteSpoon from "tastespoon"
import assert from "power-assert"
TasteSpoon.define("http", "127.0.0.1")
let server = TasteSpoon.server("http")
describe(server, () => {
let http = TasteSpoon.http("http://example.com:8080")
describe(http, () => {
it("returns 200", () => {
return http(server).result().then((response) => {
assert(response.statusCode == 200)
})
})
})
})
$ ./node_modules/.bin/mocha --compilers js:espower-babel/guess http_test.js
example.comへのリクエストはTasteSpoonの内部でhttp
サーバとして定義された127.0.0.1
へと差し向けられるので、心配は無用である。また、HTTPリクエストの結果はPromiseとして返されるので、.catch()
されることが想定されるというテストも書くことができる。
慣れたらDockerを立ち上げて、コンテナ内でNginxを動かしてテストするのも試してみてほしい。
mocha統合モード
どうだろう、元になったInfratasterに構文が近いと感じるだろうか。それとも全く似ていないと感じるだろうか。構文をもう少しだけInfratasterに似せられるような、mocha統合モードも用意した。
import TasteSpoon from "tastespoon"
import assert from "power-assert"
TasteSpoon.define("http", "127.0.0.1")
describe(server("http"), () => {
describe(http("http://example.com:8080"), () => {
it("returns 200", () => {
return this.result().then((response) => {
assert(response.statusCode == 200)
})
})
})
})
$ ./node_modules/.bin/mocha --compilers js:espower-babel/guess --ui tastespoon/mocha http_test.js
これでいくらか見た目は近くなったが、突如this
が出現するので、JavaScriptの特殊なthis
をOO式のthis
に変えてしまうAltJSとは相性が悪いので要注意。
次回予告
第一歩の解説は終了したので以下の内容を予定している。
- 待ち合わせのテストでコードがダサくなるという問題が、TasteSpoonとmochaでどう解決されるか
- TasteSpoonプラグインの作り方