Saturday, April 18, 2009

Standalone autotest with Rspec 1.2.0

If you're looking for how to do autotest with Rspec for standalone project, you might end up with this old article from 2007. But sadly, it doesn't work anymore with the latest Rspec (1.2.0).

After angrily scratching your head for why it doesn't work, you might dive into the source code and eventually solved the problem by writing some code. Then you found out that it's already supported by Rspec, no extra code required and you wondered why you didn't think of that. After all, if the problem seems common enough, somebody must have solved it. (Replace you with I)

And how do you do it? Let's dive in.

  1. Install Rspec and ZenTest.

    gem install rspec
    gem install ZenTest

  2. Set up Rspec.

    Create spec folder at your project root and put your spec files inside.

  3. Run autospec.

    Type autospec at your project root and it's done. I thought it's autotest and ended up wasting time figuring out why it doesn't work.


That's basically all, but there is more.

Adding color and other spec options


Just create spec.opts file inside spec directory. Fill it with some options, for example:

--color
--reverse

You can see the list of options available by executing spec --help.

Scan spec files within subdirectories


For one, the default behavior only scans spec files inside spec directory non-recursively. So if you like to organize your spec better, you're out of luck. But here is how to do it. In .autotest file in your project root, add the following code:

module Autotest::RspecMod
Autotest.add_hook :initialize do |autotest|
# Map to all "*_spec.rb" files inside spec and its sub directory.
regexp = %r%^lib/(.*)\.rb$%

autotest.remove_mapping(regexp)
autotest.add_mapping(regexp) do |filename, m|
autotest.files_matching(%r%^spec/.*#{m[1]}_spec.rb$%)
end
end
end


Pop up notification on Ubuntu


If you're on Ubuntu, you can follow these steps to have pop up notification when the test is finished. First, make sure you have libnotify-bin by running:
sudo apt-get install libnotify-bin


Then add the code below in .autotest.

require 'autotest/redgreen'

module Autotest::GnomeNotify
# Time notification will be displayed before disappearing automatically.
EXPIRATION_IN_SECONDS = 3
ERROR_ICON = 'gtk-dialog-error'
PENDING_ICON = 'gtk-dialog-warning'
SUCCESS_ICON = 'gtk-dialog-info'

# Convenience method to send an error notification message
#
# [title] Notification message title.
# [message] Core message for the notification.
# [icon] An icon filename or stock icon to display.
# [urgency] The urgency level (low, normal, critical).
# [time] The timeout in milliseconds at which to expire the notification.
def self.notify(title, message, icon, urgency='low', time=(EXPIRATION_IN_SECONDS * 1000))
`notify-send -i #{icon} -u #{urgency} -t #{time} '#{title}' '#{message}'`
end

Autotest.add_hook :ran_command do |autotest|
results = [autotest.results].flatten.join("\n")
output = results.slice(/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+pending)?/)

if output =~ /[1-9]\d*\spending?/
notify 'PENDING:', "#{output}", PENDING_ICON, 'normal', 5000
elsif output =~ /0 failures/
notify 'PASS:', "#{output}", SUCCESS_ICON
else
notify 'FAIL:', "#{output}", ERROR_ICON, 'critical', 10000
end
end
end

0 comments: