マイペースなRailsおじさん

Ruby、Ruby on Rails、オブジェクト指向設計を主なテーマとして扱います。だんだん大きくなっていくRuby on Rails製プロダクトのメンテナンス性を損なわない方法を考えたり考えなかったりしている人のブログです。

フラットなファイル構成のディレクトリでguardを使ってrspecを自動実行する

やりたいこと

下記のように、rubyソースコード、specファイル、Guardfileが全て一つのディレクトリにフラットに配置されている環境で、guardによる自動テスト実行を行いたい。

root_dir
├── Guardfile
├── gilded_rose.rb
└── gilded_rose_spec.rb

設定方法

guard, guard-rspecをインストールする

上記のような配置の場合、bundleを使っていることは考えにくいのでシステムにインストールしておく。

gem install guard guard-rspec

Guardfileを作成

root_dirにGuardfileを作成し、下記を記述する。

guard :rspec, cmd: 'rspec', spec_paths: ["./"] do
  watch(%r{.+_spec\.rb$}) { |m| "./#{m[0]}" }
  watch(%r{(.+)(?!_spec)\.rb$}) { |m| "./#{m[1]}_spec.rb" }
end

guardを実行

guard

guardを実行してから、rubyファイルかspecファイルを更新すれば、自動的にspecが実行される。

上記のように設定する理由

デフォルトの設定だと自動実行されないため。 デフォルトでは、実行ファイルはlibディレクトリ配下、specファイルはspecディレクトリに配置されていることが想定されている。したがって、カレントディレクトリ配下でも動くように設定を変えてやる必要がある。

ポイント

  1. spec_pathsにカレントディレクトリを設定する
    guardはこれをテスト用のファイルが入っているディレクトリとみなす。ここに入っていないテストの実行は防止する仕組みになっている。

  2. watchのブロックの返り値に./がつくようにする
    ファイルの変更を検出すると、watchのブロックを評価した結果のパスで指定されるspecファイルを実行するが、これがspec_pathsに入っているか確認している。spec_pathsに./と指定しているので、ブロックの返り値のパスが./で始まっていないと対象のフォルダに入っていないとみなしてしまう。

実行するファイルのフィルタは下記のソースコードを参照。 guard-rspec/base_inspector.rb at master · guard/guard-rspec · GitHub