Spork/Zeus/Spring によるテスト実行時間の短縮
2013/10/09
この連載の「はじめに」で予告したように、そろそろ Zeus について書こうかなと思って下調べを始めると、最近は Spring という新顔も登場して人気が出てきていることが分かりました。そこで、Zeus と Spring の両方を紹介しようと思います。
Zeus も Spring も Rails application preloader と総称されるソフトウェアの仲間です。テストを実行する度に Rails アプリケーションをロードするのは時間の無駄なので、サーバとしてプリロードしておき、テストの実行時間短縮を目的としたものです。古くから使われているものとしては、Spork というものがあります。しかし、Spork については簡単に触れるだけにとどめます。
参考文献:
- Improving Rails boot time with Zeus (2013/01/10)
- Rails使いよspork, zeusからspringへ! (2013/02/18)
- Fast Rails Commands (2013/04/04)
- spork, spring, zeus, 使わない, ... どれがオススメですか (2013/06/11)
Spork/Zeus/Spring の比較
基本的なデータで3つのソフトウェアを比較してみます。「ダウンロード数/日」は、RubyGems.org に出ている最新版のダウンロード数をリリース日からの経過日数で割った数です。
名称 | 最初のリリース日 | 最後のリリース日 | ダウンロード数/日 | 自動リロード機能 | JRuby/Windows サポート |
---|---|---|---|---|---|
Spork | 2009/05/30 | 2013/09/14 | 1,382 | No | Yes |
Zeus | 2012/07/25 | 2013/05/21 | 494 | Yes | No |
Spring | 2013/02/07 | 2013/06/21 | 159 | Yes | No |
Spork はすでに4年以上の歴史を持っています。1年2ヶ月のZeus、8ヶ月のSpringと比較するとかなりの古株です。Spork は、JRuby と Windows をサポートしている点も特長です。
しかし、Zeus と Spring には Rails アプリケーションのソースコードが編集されたときに、自動的に再読み込みしてくれるという重要な長所があります。Mac OS X または Linux を使用している方には Zeus か Spring がお勧めです。
Zeus の使い方
まず、gem
コマンドでインストールします:
$ gem install zeus
Gemfile
に gem 'zeus'
を加えて bundle install
する方法でもインストールできますが、この方法は推奨されていません。
次に spec/spec_helper.rb
から次のような行を探し、あれば削除します:
require 'rspec/autorun'
Zeus を使わない場合でも、この行はそもそも不要です。ruby -Ispec spec/models/customer_spec.rb
のように ruby
コマンドから直接実行する場合にだけこの行が必要となります。
設定ファイルを作成します:
$ zeus init
エディタで zeus.json
を開くと、初期状態は次のようになっています:
{ "command": "ruby -rubygems -r./custom_plan -eZeus.go", "plan": { "boot": { "default_bundle": { "development_environment": { "prerake": {"rake": []}, "runner": ["r"], "console": ["c"], "server": ["s"], "generate": ["g"], "destroy": ["d"], "dbconsole": [] }, "test_environment": { "cucumber_environment": {"cucumber": []}, "test_helper": {"test": ["rspec", "testrb"]} } } } } }
Cucumber を使わない人は、下から7行目を削除してください。
"cucumber_environment": {"cucumber": []},
Zeus を使用する際には、ターミナルウィンドウが少なくとも2個必要です。1個のターミナルで Zeus サーバが動き、それ以外のターミナルでテストを実行します。
Zeus サーバを起動します。
$ zeus start
すると、ターミナルに次のように表示されます:
Starting Zeus server [ready] [crashed] [running] [connecting] [waiting] boot └── default_bundle ├── development_environment │ └── prerake └── test_environment └── test_helper Available Commands: [waiting] [crashed] [ready] zeus rake zeus runner (alias: r) zeus server (alias: s) zeus destroy (alias: d) zeus generate (alias: g) zeus console (alias: c) zeus dbconsole zeus test (alias: rspec, testrb)
別のターミナルで、テストを実行します:
$ zeus rspec spec/
現行の Sinope のテストを私の PC で実行してみたところ、Zeus 抜きでは 3.67 秒かかりましたが、Zeus 環境下で実行すると 2.58 秒で終わりました。
Spring の使い方
まず、Gemfile
に以下のコードを追加します:
group :development do gem 'spring' gem 'spring-commands-rspec' end
そして、bundle install
コマンドを実行します。
何も準備は要りません。いきなり、テストを実行できます:
$ spring rspec spec/
Zeus の場合と異なり、Spring はバックグランドで黙ってサーバを起動するので、私たちが別ウィンドウで明示的にサーバを起動する必要がないのです。
常に Spring を使って RSpec のテストを実行するのなら、bin
ディレクトリの rspec
コマンドを書き換えてしまうといいでしょう。次のコマンドを実行すると、自動的に書き換えが完了します:
$ spring binstub rspec
bundle binstub rspec
を実行すると bin/rspec
の中身が元に戻ってしまうので注意してください。
すると、今後は Spring の存在を意識せずに RSpec のテストを実行できます:
$ bin/rspec spec/
現行の Sinope (この連載で作っている Rails アプリケーション)のテストを私の PC で実行してみたところ、初回はサーバの起動に時間がかかるため 4.03 秒かかりましたが、2回目からは 2.74 秒で終わりました。
Zeus vs. Spring
私の環境においては Zeus の方が若干速かったのですが、Spring の方がインストール時も使用時も手間がかかりませんでした。また、bin/rspec
を書き換えてくれる機能も便利です。
長期に渡って使用してみないことには何とも言えませんが、Spring の第一印象は素晴らしいものでした。
とはいえ、結論を出すには時期尚早でしょう。Ruby 業界におけるこの種のツールの栄枯盛衰は非常に激しいので、また半年後にはどうなっているか分かりません。
次回は
次回からは、ここのところ出番のなかった Capybara 先生に再登場いただく予定です。では、また。
[更新] spring
と spring-commands-rspec
を Gemfile
経由でインストールするように記述を変更しました。(2013/11/11)