4

I am writing a Ruby script designed to run from the command line. The script has a corresponding RSpec file that verifies its functionality. The folder structure is:

./main_script.rb
./spec/main_script_spec.rb

Running rspec spec in the top level directory works as expected. Test results from the ./spec/main_script_spec.rb file are shown. I'd like to avoid running this manually every time I change either the main script file or the spec file. All my search results turn up things like guard which (as far as I can tell) are all designed for Rails apps.

How do I setup RSpec to watch for script or spec changes and run automatically with non-Rails Ruby code?

Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96

4 Answers4

9

Like David said, Guard can be used to watch a wide variety of files and perform actions when those files are modified. It does not have to be used with a Rails app. I have set up something similar in the past using guard. Here is what I did:

Place the following in your Gemfile:

source 'https://rubygems.org'

gem 'guard'
gem 'guard-shell'
gem 'rspec'
gem 'rb-fsevent', '~> 0.9'

Then run:

$ bundle install

Create a Guardfile in your home directory with:

$ guard init

In the Guardfile, comment out the examples and add this:

guard :shell do
  watch(%r{^*\.rb}) { `bundle exec rspec spec/` }
end

This tells guard to watch for modifications to any ruby files in the directory and execute the command bundle exec rspec spec/ when they change (the backticks are used to execute the command in the shell).

Then open up a new terminal window in your current directory and start a guard server to start watching the files:

$ bundle exec guard

Now your Rspec test suite should automatically run when you modify ruby files in the directory.

Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
allareri
  • 173
  • 2
  • 7
  • I had to add some additional gem to get it to work on my machine (running Ruby 1.9.3-p392 and guard 1.7.0). I've updated the answer to include those calls. Once they were in place, it works great. – Alan W. Smith Jul 31 '13 at 17:27
3

I used guard at the past, but now I'm using a combination of rspec focus feature and watch command.

It's very simple, just add an f before a describe of it block you want to run the test. So it would becomes fdescribe or fit block. This is the same as adding a tag :focus => true to your block.

We can then filter specs with the focus tag: rspec -t focus

Now, to keeping running theses specs (every 0.5 seconds) with focus tag we call it with watch command:

watch -n 0.5 rspec -t focus

But with that the output won't show colors. So, we need to use with unbuffer.

sudo apt-get install expect

With a little customization:

watch -n 0.5 --color 'unbuffer bundle exec rspec -t focus'

Since it's annoying to type this all, I made two alias at my ~/.bash_aliases file (your can use .bashrc as well):

alias focus="watch -n 0.5 --color 'unbuffer bundle exec rspec -t focus'"
alias focuss="bundle exec rspec -t focus"

Now I can type focus to keep running it, or for a single focus execution I type focuss

Eduardo Santana
  • 5,780
  • 3
  • 19
  • 21
2

Guard can be used for plain old ruby. I generally have trouble with guard so I like to use watchr, another gem. With a few lines of code you can tell watchr to watch for changes to your files and run a command when they change.

For an example of guard with plain ruby, see the shuhari gem.

update on watchr gem: There appears to be an issue with this gem, perhaps with versions of ruby >= 2.0. The observr gem addresses this issue and works as expected in ruby 2.3.

dtburgess
  • 613
  • 5
  • 19
David Grayson
  • 84,103
  • 24
  • 152
  • 189
0

I have used guard and the guard-rspec addition with great results, and I don't believe it to be Rails-specific. Other Ruby/RSpec projects should work equally well.

The guard documentation recommends the use of Bundler and to "always run Guard through Bundler to avoid errors". I.e. you install it through your Gemfile and always run it with bundle exec guard (or use rubygems-bundler to avoid the bundle exec part).

vgoff
  • 10,980
  • 3
  • 38
  • 56
lime
  • 6,901
  • 4
  • 39
  • 50