At Jetpack we are big fans of Test Driven Development(TDD), and specifically Behavior Driven Development(BDD) using excellent testing frameworks like RSpec and Cucumber. When you are using ZenTest’s autotest or autospec, it’s nice to have unobtrusive notifications of passing/failing tests while you work. Mac users can integrate autotest with the excellent Growl, but what about us Linux users? Well be can use a library called lib-notify.
First lets play with the lib-notify binary. Install it:
sudo apt-get install libnotify-bin
To make sure it is working, try this:
notify-send "Hello World!"You should see the notification appear! Now lets edit our ~/.autotest file to use that notification:
vi ~/.autotest
module Autotest::GnomeNotify # Time notification will be displayed before disappearing automatically EXPIRATION_IN_SECONDS = 2 ERROR_STOCK_ICON = "gtk-dialog-error" SUCCESS_STOCK_ICON = "gtk-dialog-info" # Convenience method to send an error notification message # # [stock_icon] Stock icon name of icon to display # [title] Notification message title # [message] Core message for the notification def self.notify stock_icon, title, message options = "-t #{EXPIRATION_IN_SECONDS * 1000} -i #{stock_icon}" system "notify-send #{options} '#{title}' '#{message}'" end Autotest.add_hook :red do |at| notify ERROR_STOCK_ICON, "Tests failed", "#{at.files_to_test.size} tests failed" end Autotest.add_hook :green do |at| notify SUCCESS_STOCK_ICON, "All tests passed, good job!", "" end end
Although not quite as pretty as Growl yet, it works! If you are happy with that you can stop there. If you want something that looks a little bit nicer, read on!
The next few steps are going to require a few development libraries and gems, so install the following packages to make sure we are on the same page:
apt-get install libinotify-ruby libgtk2-ruby libnotify-dev sudo gem install zentest autotest autotest-rails red-green launchy
Unfortunately the libnotify ruby library isn’t included in Ubuntu 9.04 Jaunty, so we will have to build that ourselves:
wget http://rubyforge.org/frs/download.php/27134/ruby-libnotify-0.3.3.tar.bz2 tar -xvjpf ruby-libnotify-0.3.3.tar.bz2 cd ruby-libnotify-0.3.3 ruby extconf.rb make sudo make install
Next put the following pretty images in your ~./autotest_images directory:
Now we can use a modified version of Linden LAN’s .autotest:
require 'rnotify' require 'launchy' require 'gtk2' module Autotest::RNotify class Notification attr_accessor :verbose, :image_root, :tray_icon, :notification, :image_pass, :image_pending, :image_fail, :image_file_pass, :image_file_pending, :image_file_fail, :status_image_pass, :status_image_pending, :status_image_fail def initialize(timeout = 5000, image_root = "#{ENV['HOME']}/.autotest_images" , report_url = "doc/spec/report.html", verbose = false) self.verbose = verbose self.image_root = image_root self.image_file_pass = "#{image_root}/pass.png" self.image_file_pending = "#{image_root}/pending.png" self.image_file_fail = "#{image_root}/fail.png" raise("#{image_file_pass} not found") unless File.exists?(image_file_pass) raise("#{image_file_pending} not found") unless File.exists?(image_file_pending) raise("#{image_file_fail} not found") unless File.exists?(image_file_fail) puts 'Autotest Hook: loading Notify' if verbose Notify.init('Autotest') || raise('Failed to initialize Notify') puts 'Autotest Hook: initializing tray icon' if verbose self.tray_icon = Gtk::StatusIcon.new tray_icon.pixbuf = Gdk::Pixbuf.new(image_file_pending,22,22) tray_icon.tooltip = 'RSpec Autotest' puts 'Autotest Hook: Creating Notifier' if verbose self.notification = Notify::Notification.new('X', nil, nil, tray_icon) notification.timeout = timeout puts 'Autotest Hook: Connecting mouse click event' if verbose tray_icon.signal_connect("activate") do Launchy::Browser.new.visit(report_url) end Thread.new { Gtk.main } sleep 1 tray_icon.embedded? || raise('Failed to set up tray icon') end def notify(icon, tray, title, message) notification.update(title, message, nil) notification.pixbuf_icon = icon tray_icon.tooltip = "Last Result: #{message}" tray_icon.pixbuf = tray notification.show end def passed(title, message) self.image_pass ||= Gdk::Pixbuf.new(image_file_pass, 48, 48) self.status_image_pass ||= Gdk::Pixbuf.new(image_file_pass, 22, 22) notify(image_pass, status_image_pass, title, message) end def pending(title, message) self.image_pending ||= Gdk::Pixbuf.new(image_file_pending, 48, 48) self.status_image_pending ||= Gdk::Pixbuf.new(image_file_pending, 22, 22) notify(image_pending, status_image_pending, title, message) end def failed(title, message) self.image_fail ||= Gdk::Pixbuf.new(image_file_fail, 48, 48) self.status_image_fail ||= Gdk::Pixbuf.new(image_file_fail, 22, 22) notify(image_fail, status_image_fail, title, message) end def quit puts 'Autotest Hook: Shutting Down...' if verbose #Notify.uninit Gtk.main_quit end end Autotest.add_hook :initialize do |at| @notify = Notification.new end Autotest.add_hook :ran_command do |at| results = at.results.last unless results.nil? output = results[/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+pending)?/] if output failures = $~[2].to_i pending = $~[4].to_i end if failures > 0 @notify.failed("Tests Failed", output) elsif pending > 0 @notify.pending("Tests Pending", output) else unless at.tainted @notify.passed("All Tests Passed", output) else @notify.passed("Tests Passed", output) end end end end Autotest.add_hook :quit do |at| @notify.quit end end
This should leave you with a pretty good base if you want to further customize the script!




September 9th, 2009 at 1:00 am
[...] Autotest Notifications on Ubuntu, extremely useful for me as an Ubuntu use Tags: agile, bdd, database, linux, scrum, ubuntu Comment (RSS) | Trackback [...]
September 9th, 2009 at 5:24 pm
wheeeeeee a ruby user!
PS: I think you should add a link your code + image, would be more convenient for people to just download and extract rather than copy/paste
September 15th, 2009 at 4:02 pm
ruby-libnotify builds properly on jaunty but when you try to use it, it sort of causes segmentation fault saying
symbol lookup error: /usr/local/lib/site_ruby/1.8/i486-linux/rnotify.so: undefined symbol: rbgobj_instance_from_ruby_object
this library is under wishlist section of jaunty.
I think we might have to wait for bug free version to get in.
November 3rd, 2009 at 11:54 pm
ruby-libnotify doesn’t seem to want to compile on Ubuntu Karmic. I searched around and haven’t found a solution. Pasting the error here: http://pastie.org/682847
November 15th, 2009 at 7:37 pm
Ramon, install ruby-gnome2-dev to get the rbgobject.h file.
November 18th, 2009 at 7:54 pm
I just tried to run the modified autotest, and I get the following error:
uninitialized constant Autotest (NameError)
I’m on ubuntu 9.10, 64 bit.