Rails3でTDD環境を整えたメモ

2011/07/07追記

実はこの記事の内容よりも以下のGuardを前提にした構築がおすすめ。

Rails3+RSpec2+Spork+Guard(guard-rspec,guard-cucumber)で最速のBDD(振舞駆動開発)環境を作る | Curiosity Drives Me

Guard便利すぎです。

久々にRailsでできる仕事が来たので久々に環境構築。
記事の一番最後に挙げた参考の渡り歩きつつ設定した。

Rubyのバージョンは1.9.2。Railsは3.0.5。

プロジェクトの作成

$ rails new -T hoge

RSpecを使うのでUnitTestはいらないということで。

Gemfile

必要なものをBundlerでさくっと入れる。

group :development, :test do
  gem 'spork', '~> 0.9.0.rc'
  gem 'rspec-rails'
  gem 'autotest-rails'
  gem 'webrat'
  gem 'cucumber'
end

Gemfileを編集したら

$ bundle install

webratとcucumberは直近では用がなさそうだけどとりあえず入れた。

RSpecの設定

$ rails g rspec:install

ここまででRSpecを実行する環境は整った。
すばらしい簡単さだ。

sporkで速度向上

しかしRSpecの実行がひどく遅くていきなりストレスに直面する。
どうもRailsのロードに時間がかかっているらしい。

そこでsporkを使ってRailsをロード時間を節約することで実行がだいぶ速くなる。

spec/spec_helper.rb
$ spork --bootstrap

を実行すると自動でspec_helper.rbの内容がspork対応に更新される。

Rails3でsporkを使う場合は0.8.4だとこのままではテスト対象のRailsのコードを修正してもspork上に反映されない問題がある。
そのためこれに加えて手動での修正が必要になる。

が、0.9.0(現時点ではrc)を使うことで問題はなくなる。

.rspecの編集

RSpecがspork経由で動くようにするため、–drbオプションを追加する。

--color --drb
起動
$ spork

RSpecが動き出すまでがすばらしく速くなった。

autotest

実は今までautotest環境で本格的に開発したことがないのだが、今回試してみることにした。

autotest-railsのおかげなのか以前と比べるとだいぶ導入が簡単になっていた。

.autotestの編集

ここのスクリプトをほぼそのまま使った。
アイコンはイカちゃんにした。

実行
autotest

Growl

autotestの結果を通知するのにないとさびしい。
growlnotifyを入れてなかったので、Growl公式から落としてきて入れた。

あとはGrowlの設定をして環境構築Done。

参考

参考にさせてもらった方々あざっした!

2011/03/18追記

autotestおとろしく便利だった。

で、使っているうちに実行エラーとテストの失敗を区別したく思えてきたので.autotestを以下のように書き換えた。
Growlの重要度も変えて、エラー時は背景色を紫にするようにした。

# coding: utf-8

IMG_OK = '~/.autotest_icons/ok.gif'      # 成功時の画像
IMG_NG = '~/.autotest_icons/fail.gif'    # 失敗時の画像
IMG_PD = '~/.autotest_icons/pending.gif' # 保留時の画像
IMG_ER = '~/.autotest_icons/error.gif'   # エラー時の画像

module Autotest::Growl
  def self.growl title, msg, img="~/.rails_ok.png", pri=0, sticky=""
    msg += " at #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
    system "growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}"
  end

  Autotest.add_hook :ran_command do |at|
    output = at.results.last.chomp!
    output =~ /((?:\d+) examples?, (\d+) failures?(?:, (\d+) pendings?)?)/
    if $2.nil? && $3.nil?
      growl "Tests Errored", "errors", IMG_ER, 2
    else
      if $2.to_i > 0
        growl "Tests Failed", "#{$1}", IMG_NG, 1
      else
        if $3.to_i > 0
          growl "Pending", "#{$1}", IMG_PD, -1
        else
          growl "Tests Passed", "#{$1}", IMG_OK, -2
        end
      end
    end
  end
end

ちなみにWEB+DB PRESS Vol.61を見たらautotestよりもguard-rspecなるものが最近はナウいようだ。
気が向いたら試してみよう。
この号のRails3テスト最前線の記事は他にもいろいろとかなりよかったのでおすすめ。