Experiences on the Front Lines of User Interfaces and Web Development

Growl notifications with Rails Autotest

For Ruby on Rails development, using the "Autotest" gem is a handy way to constantly have tests running in the background, to notify you of when tests fail. The great feature is that it diffs your changes since it last run, so as to only run relevant tests. This tool is great if you have a ton of screen real estate to dedicate a terminal window just for autotest so you can be monitoring the results periodically. But no serious developer has free screen space! That's where Growl notifications come in. If you aren't familiar with Growl, it is a cool Mac OS X specific application that applications can use for notifying you of events (calendar reminders, downloads, etc).

It is possible to connect Growl notifications to Autotest such that you get a notification each time tests are run and either pass or fail. There's many tutorials out on the web, but I struggled to find a single, concise, and accurate tutorial on how to set it up. And read further for how to fix the Mac Leopard / Growl bug.

1. Install Autotest
> sudo gem install ZenTest
You should now be able to run "autotest" from your rails project directory.

2. Install Growl
Download the Growl image here.
Copy growlnotify (found in the "Extras\growlnotify" folder of the Growl dmg) to somewhere that is in your path. (One suggestion is in /usr/local/bin directory).

Verify it’s running by entering:
> growlnotify -m "Testing" Hello World!
You should see a Growl notification

3. Create AutoTest Hook
Create an init file for autotest: ~/.autotest

Insert the following contents (replace the image paths with something that exists on your computer!):

module Autotest::Growl
def self.growl title, msg, img, pri=0, stick=""
system "growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{stick}"

Autotest.add_hook :ran_command do |at|
output = at.results.last.slice(/(\d+).*errors/)
if output =~ /ns.*[1-9]/
growl "Test Results", "#{output}", '~/Library/autotest/rails_fail.png', 2 #, "-s"
growl "Test Results", "#{output}", '~/Library/autotest/rails_ok.png'

Images you can use:

4. Launch Autotest
If you modified your path at all while setting up growlnotify, I suggest you restart your terminal. Simply opening new tabs for me was causing the autotest/growlnotify interaction to be flaky.
Restart autotest if it is still running. Now go and edit a test such that it fails. Voila, you should see a red growl notification!

5. But wait, my notifications aren't appearing
If you find that autotest is running, and growlnotify command is being invoked correctly (by putting trace in the .autotest file for example), but your growl notifications aren't appearing, here is a workaround:

A bug exists in Growl such that with Leopard, the growlnotify success rate is about 1/3 of the time. (https://bugs.launchpad.net/growl/+bug/267767)

a) Rename growlnotify to growlnotify.wrapped
b) Create a file called growlnotify and insert:

exec $wrappee -w "$@" &

c) Add execute permissions to it: > chmod +x growlnotify
Ensure that you can still run growlnotify commands by trying the test above a few times

(To find out more about his fix, visit the bug page or here: http://hans.fugal.net/blog/2008/02/13/growling)

If you go into the growl notification settings (in System Preferences), you can change the background color of various priorities. The script above marks "failed test" notices as priority 2, so its on the "emergency" setting. I recommend a dark red background.

Note: This setup worked for me with ZenTest 3.11.0 and growlnotify 1.1.4 on Mac OS X 10.5.5



Glad this helped. I spent too long pulling my hair out thinking I had something wrong with AutoTest, then to find out it's a Growl <-> Leopard communication issue.

I also later read that if you don't use an image in your notification, the issue is not present. I did not totally confirm that, but it could be a simpler solution for others that run into this problem.
Totally awesome thanks Nick! From Growl => Rails Growl is a little arcane and your guide worked first time! Thanks particularly for adding the version numbers you tested it with, that's how I found it on Google.

comments powered by Disqus