Autospecを使ってRSpecのテストを自動化 with Growl

まずはgemのインストール

$ gem i ZenTest
$ gem i redgreen
$ gem i ruby-growl

growlで使う画像の取得。

別にwgetでもいいけどなんとなくcurl.

$ curl http://blog.internautdesign.com/files/rails_fail.png > ~/rails_fail.png
$ curl http://blog.internautdesign.com/files/rails_ok.png > ~/rails_ok.png

growlnotifyを入れていなかったので入れる。

うちはhomebrewを使っていますが、MacPortsの方は読み替えて下さい。

$ brew install growlnotify

~/.autotestの編集

# -*- ruby -*-

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|
    results = [at.results].flatten.join("\n")
    output = results.slice(/\d+\s+examples?,\s*(\d+)\s+failures?/)
    if output
      if $~[1].to_i > 0
        growl "Tests Failed", "#{output}", "~/.rails_fail.png", 2
      else
        growl "Tests Passed", "#{output}", "~/.rails_ok.png", -2
      end
    else
      growl "Tests Errored", "errors", "~/.rails_fail.png", 2
    end
  end
end

ちなみに上記の設定だと数秒でgrowlの表示が消えますが、エラー等は数秒で消したくないという方もいらっしゃるとおもいます。そういう方は最後に"-s"を付けると明示的にそのメッセージを消すまで、表示され続けます。

growl "Tests Failed", "#{output}", "~/.rails_fail.png", 2
でなくて
growl "Tests Failed", "#{output}", "~/.rails_fail.png", 2, "-s"

specを適当に書く

spec/message_filte_spec.rb

require 'rubygems'
require 'spec'
require 'message_filter'

describe MessageFilter do
  it 'should detect NG word' do
    filter = MessageFilter.new('foo')
    filter.detect?('hello from foo').should == true
  end
end

message_filter.rb

class MessageFilter
  def initialize(word)
    @word = word
  end
  def detect?(text)
    true
  end
end

spec/spec.opts

-fs
-c

autospecの実行

$ autospec
...
MessageFilter
- should detect NG word
Finished in 0.00885 seconds
1 example, 0 failures

これでgrowlメッセージがでれば大成功。だめでも一回はCTRL-Cを押して見てください。あとはgrowlの設定を開き、アプリケーションからautotestを選び、通知の表示スタイルでお好みのスタイルにすれば終了。私はBubblesを選びました。