RSpec を autotest で使う

あんまりまとまってないけど書く。
むしろまとめるために書く。
重要なのはアウトプットすることで
「分かったところまででいいからとにかく書いた方がいいよ」
ってえらい人が言ってた。

できていること

「./hoge.rb」と「./spec/hoge-spec.rb」がある状態で「autotest」を実行すると
「./spec/hoge-spec.rb」を保存した時点でテストが自動実行される。
また、そのときのテスト結果は画像付きでポップアップで表示される。

RSpec

Ruby のためのテストツール。

gem install rspec

でインストールできる。

autotest

Zentest というテスト環境の一部。
ファイルを保存したときに自動でテストを行うためのツール。

gem install zentest

でインストールできる。

Snarl

ポップアップで文字や画像を表示するツール。
MacGrowlWindows 版。みたいな。
Snarl を使うと autotest の結果をポップアップで表示できる。かこいい(・∀・)
インストールは公式の downloads から。
Snarl

.autotest

ホームディレクトリに以下を「.autotest」として保存している。
autotest は「.autotest」にある内容を優先して読み込む。らしい。
雛形の「example_dot_autotest.rb」は ZenTest をインストールしたディクレトリの直下にある。
(例えば「c:/Ruby/lib/ruby/gems/1.8/gems/ZenTest-3.9.2/」)
autotest をカスタマイズする場合はまずこの雛形をホームディレクトリに持ってきて
名前を「.autotest」に変更するのが基本っぽい。


以下は
Day by day - Railsのテスト環境を改めて- Windows / RSpec / ZenTest / Snarl

autotest をカスタマイズする - 観測所日誌
をめっさ参考にして書いた現時点での僕の .autotest
rails_ok.png」と「rails_fail.png」は
autotest をカスタマイズする - 観測所日誌から持ってきた。

require 'autotest/redgreen'

Autotest.add_discovery do
  "rspec"
end

Autotest.add_hook :initialize do |at|
  at.add_mapping(/([\w0-9]+)\.rb$/) do |f, matched|
    "#{matched[1]}_spec.rb"
  end
end


#### Snarl
require 'rubygems'
require 'snarl'

module Autotest::Snarl
  def self.icon
    path = File.dirname(__FILE__)
    
    {
      :green => "#{path}/rails_ok.png",
      :red => "#{path}/rails_fail.png",
      :info => ''
    }
  end
 
  def self.snarl title, msg, img=nil
    Snarl.show_message(title, msg, icon[img])
  end
  
  Autotest.add_hook :ran_command do |at|
    results = [at.results].flatten.join("\n")
    output = results.slice(/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+not implemented)?/)
    if output
      if $~[2].to_i > 0
        snarl "Test Results", "#{output}", :red
      else
        snarl "Test Results", "#{output}", :green
      end
    end
  end
end
 
class Autotest
  def self.clear_hook
    HOOKS[:red].clear
    HOOKS[:green].clear
    HOOKS[:all_good].clear
  end
end
Autotest.clear_hook

参考先との違いは2箇所。


まず、上の方にあるコメントアウトされたコードは
autotest をカスタマイズする - 観測所日誌を参考に書いたもの。
参考先では「"spec/#{matched[1]}_spec.rb"」ってなっているところが
僕のだと「"#{matched[1]}-spec.rb"」になっている。
こうしておくと、テストファイルが「spec」ディレクトリ以下になくても
テストを実行してくれるようになる。
デフォルトの設定では「spec」以下しか見てくれない。
この設定は「RSpec」のソースを読めば分かると思う。
だけどそんなにちゃんとは読んでないので断言はできない。


参考先と違う2つ目の点は、「#### Snarl」のあたり。
参考先のDay by day - Railsのテスト環境を改めて- Windows / RSpec / ZenTest / Snarlでは
「require 'autotest/snarl'」となっているが
僕は「require 'rubygems'; require 'snarl'」にしている。
「require 'autotest/snarl'」にしておくと「redefine」がどうのと言われる。
しかも「C-c」で抜けられなくなる。なので置き換えた。


雛形の「example_dot_autotest.rb」は
「ZenTest/lib/autotest」以下にあるライブラリの require が
ずらーっとコメントアウトされていて、
使いたいライブラリはその都度コメントインするような構造になっている。
「ZenTest/lib/autotest/snarl.rb」を見ると
上記の「.autotest」とかぶるものがあるから「redefine」って言われるんだろうなぁ。


それと、「C-c」で抜けられなくなるのはたぶんこれのせいだな。

  Autotest.add_hook :interrupt do |at|
    snarl "autotest", "autotest was reset", :info unless $TESTING
  end

ん。でも「:quit」っていうのもあるな。

  Autotest.add_hook :quit do |at|
    snarl "autotest", "autotest is exiting", :info unless $TESTING
  end

コマンドプロンプトから「autotest」を実行した場合
「C-c」すると「Interrupt a second time to quit」って表示される。
もう1度「C-c」すると「バッチ ジョブを終了しますか (Y/N)?」って出るから
そこで「y」を入力して終わらせている。
おそらく、最初の「C-c」で「:interrupt」が
「y」して抜けたときに「:quit」が呼び出されると思うのだけど
「:interrupt」のときに「reset」かかっちゃったら
その先の「:quit」にはいけなくないか?
もしかしたら「C-c」以外にも終了させる方法があるのかもなぁ。


ところで、本当は「eshell」から「autotest」を実行したいと思ってる。
んだけど「eshell」で実行すると終わらせられないんだよなぁ。
「C-c」してもダメって困りすぎる…。
たぶん「eshell」のフラッシュが遅いからだと思うんだけど
それ以上のことは何も分かってない(´・ω・`)
「eshell」のフラッシュについてはけっこう前から気になってる。

redgreen

たぶんテスト結果のフォントを緑や赤に染めてくれるツールだと理解している。
でも今のところ機能していない。
なんでだかも分からない。
「spec -c」はちゃんと色つくんだけどなぁ。
コマンドプロンプトだからいけないのだろうか。

diff-lcs

Day by day - Railsのテスト環境を改めて- Windows / RSpec / ZenTest / Snarl
で紹介されたので入れてみたけど何なのかよく分かってない。
Zentest の「unit_diff」の代わりなのかな?
インストールは gem で一発。

gem install diff-ls

ruby-snarl

これも「diff-lcs」と同じで
Day by day - Railsのテスト環境を改めて- Windows / RSpec / ZenTest / Snarl
で紹介されていたけどよく分からない。
Ruby から「Snarl」を動かすために必要なのかと思ってたけど
別になくても動かせるんだよなぁ。なんだろこれ。
インストールは gem で一発。

gem install ruby-snarl

その他