spec_server の話 (1)
spec_server 絡みのことをブログに書こうと思ったんですが、そもそも spec_server を使う理由なんかをブログ書いていなかったので、半年前くらいに書いてたメモをごっちゃり投稿しておきます。ちょっと情報古い上に本当にただのメモです。
2009 年 10 月当時の状況
- Rails 案件で RSpec を使ってるけど、誰もテストを実行する習慣がついてないから Failure だらけ
- Failure を潰すためにがしがしテストをやりたいけど、RSpec が遅すぎて作業がはかどらない
という感じ。
を見た感じ autotest を使うとよさそうだけど、もともと Failure だらけのところで使っても効果が薄いので、まずは spec_server だけ導入することに。
Spork を使おうとする→失敗
(※この項の最後に書いてますが、最近だと状況違うと思います。)
rspec_server を使おうとすると「Spork のほうを使いなさい」みたいな文句言われたので、Spork を試してみることに。
使い方は、
のとおり。
uninitialized constant MissingSourceFile (NameError)
のエラー回避策も載ってるんだけど、結局
>ruby script/spec --drb spec\models\user_spec.rb
(druby://127.0.0.1:8989) D:/InstantRails/ruby/lib/ruby/gems/1.8/gems/activesuppo
rt-2.3.4/lib/active_support/dependencies.rb:105:in `const_missing': uninitialize
d constant Spork::Forker::UNIXSocket (NameError)
みたいなエラーになってしまう。
このエラーについては、
- <Win32utils-devel> IO.socketpair addition -- very helpful!
- Re: Threads: Different behavior under Linux and Windows
みたいな方法で解決できるけど、その先にまた
>ruby script/spec --drb spec\models\user_spec.rb
(druby://127.0.0.1:8989) D:/InstantRails/ruby/lib/ruby/gems/1.8/gems/spork-0.7.3
/bin/../lib/spork/forker.rb:25:in `fork': fork() function is unimplemented on th
is machine (NotImplementedError)
こんなエラーが待っていると。
rspec-rails 1.2.9 Released - Ruby Forum を見ると、
* removals * spec_server has been removed in favor of spork. * You can still use the --drb flag, but you've got to install the spork gem. * Windows users who cannot use the spork gem can install the spec_server from http://github.com/dchelimsky/spec_server
とのことだから、Windows では spec_server を使いましょうと。
timcharper's spork at master - GitHub には
Because Spork uses Kernel.fork, it only works on POSIX systems. This means Windows users are not invited to this party. Sorry :(
とか書いてるので、「Sorry じゃねえよ」って方はこっちで投票するといいのかも。
でも D:\InstantRails\ruby\lib\ruby\gems\1.8\gems\rspec-rails-1.2.7.1\lib\spec\rails\spec_server.rb にあるように Process.fork とかもダメなのかなー、余裕があれば調査しようかなー・・・と思ったら、2010-03-09 にメッセージが更新されていて。
Commit b74c98985fa7d8a4d7abab4b3a91c8098b69e905 to timcharper's spork - GitHub
Spork runs on POSIX systems using fork. It also runs on windows by pre-populating a pool of ready processes (referred to here as the "magazine" strategy).
とのことなので、Windows でも Spork が使えるようになっているのかも。
spec_server の導入&使い方
spec_server ですが、
ここからダウンロードしたものを script に置いて、
ruby script/spec_server
とかやってサーバを起動しておいて、spec の実行時に --dbd オプションをつければサーバ側でテストが実行されます。ちなみに --drb は dRB(distributed Ruby=分散オブジェクトライブラリ)を使うという意味。諸々の準備がでいてるから、二回目以降のテストではテストが高速に実行されるようになります。
rake spec 時にも使いたければ、spec/spec.opts に --drb と一行追加しておけばよいです。
(2010-07-26 追記)
rspec-rails-1.2.7.1 以前?が入っていないと、以下のエラーが発生するようです。
>ruby script/spec_server Loading Rails environment D:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require': no such file to load -- spec/rails/spec_server (MissingSourceFile)
gem install rspec-rails -v 1.2.7.1 でインストールすればこのエラーは回避できるはずです。
(2010-07-27 追記)
別バージョンの rspec-rails(例えば 1.3.2)が入っている場合は、spec_server が 1.2.7.1 の環境で起動して、クライアント側のバージョンと異なってしまうため(?)、
vundefined method `handling_predicate!' for #<Spec::Matchers::Be:0x882b86c @args=[:be_valid]>
こんなエラーになってしまうようです。この場合は、ひとまず gems\rspec-rails-1.2.7.1\lib\spec\rails\spec_server.rb を gems\rspec-rails-1.3.2\lib\spec\rails\spec_server.rb にコピーしてから spec_server を起動すればうまくいきました。
全テストを一つずつ実行
rake spec で全テストが実行されるわけですが、その方法だとどのテストが失敗したかわかりにくいので、spec_all.rb とかいう名前でこんなスクリプトを用意してました。
# すべての spec を実施するためのスクリプト # # rake spec だとどの spec でエラーになったかわかりにくいので作成。 Dir.glob('spec/**/*_spec.rb').each{|file| puts '-' * 80 command = "ruby script/spec --drb -c #{file}" puts command system command }
ついでに tst.bat という名前でこんなスクリプトも準備。
ruby script/spec -c --drb %*
テストに失敗したファイル名がわかったら、
この辺で作った skr.cmd でサクラエディタを起動→spec ファイルを編集して、skr を tst に書き換えてテスト実行、みたいなことをやってました。
さて、これで前置きが終わったので、次はここ数日ハマってたことを書いていきます。