rspecを高速化するsporkとその仕組み
最近rspecでRailsのテストコードを書いてました。
書いたテストコードは動かしながら確認していくわけですが、その1回1回の実行時間がとても長くて困ってました。(私の環境では1回の実行で大体10秒くらいかかってました。)
「なんでこんな時間かかるんやろう?」と思って調べてみたところ、どうやらrspec実行の度にRails環境をロードするため時間がかかっていたようです。
rspec実行の度にRailsをロードしていたのでは時間がかかって当然ですね。
何か良い方法ないのかな?と思っていたら「spork」なるものを発見したので導入してみました。
sporkの導入
GitHub - sporkrb/spork: A DRb server for testing frameworks (RSpec / Cucumber currently) that forks before each run to ensure a clean testing state.(1)Gemfileにsporkを追加
gem 'spork'
(2)sporkのinstall
bundle install
(3)bootstrapの設定
spork rspec --bootstrap
(4)sporkの起動
spork
(5)rspecを--drbを付けて実行
rspec --drb spec/controllers/spork_tests_controller_spec.rb
(4)で起動したsporkプロセスがシステムに常駐、(5)ではそのsporkプロセスに対して操作することによってrspecの高速化が図れるそうです。
これで大体10秒かかっていたrspecの実行が即時になりました。
なんでspork導入すると早くなるの?・・・の前に
GitHub - sporkrb/spork: A DRb server for testing frameworks (RSpec / Cucumber currently) that forks before each run to ensure a clean testing state. の一番上にはこんなことが書かれてあります。A DRb server for testing frameworks (RSpec / Cucumber currently) that forks before each run to ensure a clean testing state.
sporkはRSpecやCucumberなどのテストフレームワーク用のDRbサーバです、とのこと。
sporkの仕組みを理解するためにはDRbについて理解する必要がありそうです。
DRbとはDistributed Rubyの略称で、Rubyの分散オブジェクト技術のことです。
分散オブジェクト技術といえばCORBA、DCOM、RMI、SOAP、etc… 世の中にたくさんありますね。
これだけで少しイメージが掴める気がします。
とは言っても、もう少し詳しく知りたいな〜と思って色々巡っていたらこんなページを発見しました。
drbライブラリのページなのでちょっと方向性はズレますが、DRbがどんなものかを知るためにはとても分かりやすいページでした。
ざっとまとめるとこんなことが書いてあります。
- DRb(dRuby)とはRuby専用の分散オブジェクト技術である
- 独自のプロトコル(druby://....)で通信するため、その他の分散技術との相互運用性はない
- リモートプロセスにあるオブジェクトはローカルのDRb::DRbObject インスタンスとして表現され、そのインスタンスはリモートオブジェクトのproxyのように振る舞う
- CORBAのIDLのようなインタフェースの静的宣言は必要ない(すべて実行時に解決される)
- リモート⇔ローカルではメソッドの引数/戻り値をMarshalでバイト配列に変換して受け渡しする
- dRubyはブロック付きのメソッド呼び出しをサポートするが、Procはマーシャリング不可能なのでブロックの中身はローカルプロセス上で実行される。
動作イメージはこんな感じですかね。
なんでspork導入すると早くなるの?
ではsporkの話に戻って、なぜsporkを導入すると高速化を図れるのでしょうか?これはsporkがRails環境とその関連クラスのロードを担ってくれるためです。
sporkがすでにRails環境とその関連クラスをロードしてくれているため、rspecはテスト実行だけに集中できます。
つまりRails起動相当のコストが丸々削減出来るため、高速化が図れるということになります。
さいごに
今回はsporkとその仕組みについて書いてみました。sporkはとても便利ですし、使わない手はないな〜という印象でした。