Autotest and Growl for both RSpec and Test::Unit
Posted: November 8th, 2008 | Filed under: Programming | Tags: autotest, rspec, testunit | 4 Comments »
Previously I wrote about BDD and zen testing in my post “Ruby / Rails: Zen Testing with Autotest and XOSD“. I mentioned a couple of links where you could find an .autotest script for your Linux / Mac environment to throw the results of your tests to Growl or XOSD for a nice on-screen text display. This kept you on top of background testing at all times.
Over the course of the last few months I was taking part in different Rails projects. Some of them used RSpec and some Shoulda/Mocha for unit testing. The original .autotest script that I picked and adopted was intended for RSpec, so I had to modify it over and over to support the environment I was currently working in. Finally, as I realized there was not a slightest hope to end this jumping back and forth, I came up with a multi-environment script that works with both RSpec and Test::Unit.
It detects it all automatically, and the only thing you need to do is to give the paths to your pass / fail / pending icons.
Here’s the script for your copy-pasting convenience. Name it “.autotest” and place in your home directory. Enjoy!
STATUS_ICONS = {
:pass => "~/Library/autotest/pass.png",
:fail => "~/Library/autotest/fail.png",
:pending => "~/Library/autotest/pending.png"
}
def self.growl(title, msg, img, pri=0, stick="")
system "growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{stick}"
sleep 1
end
Autotest.add_hook(:ran_command) do |autotest|
results = [ autotest.results ].flatten.join("\n")
rspec_regexp = /(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+pending)?/
test_unit_regexp = /(\d+)\s+tests?,\s*(\d+)\s+assertions?,\s*(\d+)\s+failures?,\s*(\d+)\s+errors?/
if !(output = results.scan(rspec_regexp).flatten).empty?
# RSPEC
examples, failures, x, pending = output
if failures.to_i > 0
prefix, icon, priority, stick = "FAIL:", :fail, 2, "-s"
elsif pending > 0
prefix, icon, priority, stick = "PENDING:", :pending, 2, "-s"
else
prefix, icon, priority, stick = "PASS:", :pass, 0, ""
end
info = "Examples: #{examples}"
info += " Failures: #{failures}" if failures.to_i > 0
info += " Pending: #{pending}" if pending.to_i > 0
elsif !(output = results.scan(test_unit_regexp).flatten).empty?
# Test::Unit
tests, assertions, failures, errors = output
failed = failures.to_i > 0 || errors.to_i > 0
if failed
prefix, icon, priority, stick = "FAIL: ", :fail, 2, "-s"
else
prefix, icon, priority, stick = "PASS: ", :pass, 0, ""
end
info = "Tests: #{tests}/#{assertions}"
info += " Errors: #{errors}" if errors.to_i > 0
info += " Failures: #{failures}" if failures.to_i > 0
else
# Unknown format
return
end
growl prefix, info, STATUS_ICONS[icon], priority, stick
end
end
The Ruby on Rails addict, industrial photographer and amateur electronic music composer. In the mean time I build great web applications, contribute to OSS and help AVAAZ to save Great Barrier Reef.