I've been using Autotest (part of the ZenTest package) while testing my Rails applications and never thought of asking for more. After all, getting my tests (well, specs actually) run automatically whenever I make a relevant change and having diff-level granularity on which tests Autotest re-runs is pretty damn useful enough. That is, until I came across this RSpec and Autotest with Growl notifications blog entry (on JavaBlogs, no less!)

How're these for red/green test results?

Tests (specs) passing!

Growl notification of tests passing


Tests (specs) failing :(

Growl notification of tests failing :(


Much better! Now I don't have to glance at my terminal window (I recently realized how painful it is while coding with a single monitor) and get unobtrusive notifications.

Unfortunately, this is Mac-only (or wherever Growl is supported). I had to follow links to several blog entries to get it setup nicely (see Growl + Autotest Rails with Zentest 3.4.0 and Green goodness with autotest + growl - those are my references).

Basically you need Growl installed, and the growlnotify tool in your path. growlnotify can be found in the Extras/growlnotify directory in the Growl dmg (for example, after you've mounted the Growl-0.x.x.dmg, you can find it here: /Volumes/Growl/Extras/growlnotify). Just copy the growlnotify executable into your path (I copied it into /opt/local/bin since I'm using Darwin Ports and don't have a /usr/local/bin directory). Verify it's running by entering:

growlnotify -m "Testing growlnotify" Boo Ya!

into a terminal window. You should see a Growl notification.

Now, you need to create an Autotest hook by creating an autotest init file in your home directory named .autotest, and copy this chunk of text in:


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

  Autotest.add_hook :ran_command do |at|
    output = at.results.last.slice(/(\d+)\s.*specifications?,\s(\d+)\s.*failures?/)
    if output =~ /[1-9]\sfailures?/
      growl "Test Results", "#{output}", "/Data/Pictures/Icons/rails_fail.png", 2, "-s" 
    else
      growl "Test Results", "#{output}", "/Data/Pictures/Icons/rails_ok.png" 
    end
  end
end

Replace the paths to the pass/fail icons (as you can see, mine are in /Data/Pictures/Icons/) with the correct paths to any images you want to display (grab them from Green goodness with autotest + growl or roll your own). You can change the parameters passed to growlnotify however you want (use growlnotify -h to see what parameters it acccepts). The pri parameter sets the priority level of the message (test failures come up with a priority of 2, hence the red background of the Growl notification). Passing -s to sticky tells Growl to keep the notification sticky. If you're running your (auto)tests on a remote server (e.g. in a Continuous Integration system), you can even use growlnotify to send remote notifications (see the -H switch) to your development workstations!

Lovely! I love you, MacBook Pro serial no. W86280NAVWW (despite your broken DVD drive and you randomly freezing up on me when you get too hot).