miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

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)

みたいなエラーになってしまう。

このエラーについては、

みたいな方法で解決できるけど、その先にまた

>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 に書き換えてテスト実行、みたいなことをやってました。

さて、これで前置きが終わったので、次はここ数日ハマってたことを書いていきます。