Autotest notifications on Ubuntu using lib-notify

words by Brian Racer

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
  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}'"
  Autotest.add_hook :red do |at|
    notify ERROR_STOCK_ICON, "Tests failed", "#{at.files_to_test.size} tests failed"
  Autotest.add_hook :green do |at|
    notify SUCCESS_STOCK_ICON, "All tests passed, good job!", ""

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:

tar -xvjpf ruby-libnotify-0.3.3.tar.bz2
cd  ruby-libnotify-0.3.3
ruby extconf.rb
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 =
      tray_icon.pixbuf =,22,22)
      tray_icon.tooltip = 'RSpec Autotest'
      puts 'Autotest Hook: Creating Notifier' if verbose
      self.notification ='X', nil, nil, tray_icon)
      notification.timeout = timeout
      puts 'Autotest Hook: Connecting mouse click event' if verbose
      tray_icon.signal_connect("activate") do
      end { Gtk.main }
      sleep 1
      tray_icon.embedded? || raise('Failed to set up tray icon')
    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
    def passed(title, message)
      self.image_pass ||=, 48, 48)
      self.status_image_pass ||=, 22, 22)
      notify(image_pass, status_image_pass, title, message)
    def pending(title, message)
      self.image_pending ||=, 48, 48)
      self.status_image_pending ||=, 22, 22)
      notify(image_pending, status_image_pending, title, message)
    def failed(title, message)
      self.image_fail ||=, 48, 48)
      self.status_image_fail ||=, 22, 22)
      notify(image_fail, status_image_fail, title, message)
    def quit
      puts 'Autotest Hook: Shutting Down...' if verbose
  Autotest.add_hook :initialize do |at|
    @notify =
  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
      if failures > 0
        @notify.failed("Tests Failed", output)
      elsif pending > 0
        @notify.pending("Tests Pending", output)
        unless at.tainted
          @notify.passed("All Tests Passed", output)
          @notify.passed("Tests Passed", output)
  Autotest.add_hook :quit do |at|

This should leave you with a pretty good base if you want to further customize the script!

  • Pingback: Caffeine Driven Development » Blog Archive » L33t Links #7()

  • mark

    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 ūüėÄ

  • 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/ 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.

  • Ramon

    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:

  • Ramon, install ruby-gnome2-dev to get the rbgobject.h file.

  • Sonny Parlin

    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.

  • Brian

    running ruby extconf.rb says :

    ERROR: no gtk2.rb found

  • Works wonderfully, thanks for sharing! This is a great feature for those of us who are used to using Growl in OS X. –Walter

  • Vlpeng

    Hi there,
    I followed up your instruction on my Ubuntu 11.04 with Ruby-1.9.2-p180 / Rails 3.0.9. I encountered below issue:
    /home/vlpeng/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require’: no such file to load — test/unit/ui/console/testrunner (LoadError)

    See and

    Any idea? Thanks in advance.


  • Pingback: PHPSpec Autorun-Test Notifier | Craft It Online!()