Sorry this page looks weird. It was automatically migrated from my old blog, which had a different layout and different CSS.

Filtering Autotest’s Unbuffered Output

I upgraded my ZenTest gem yesterday and was delighted to see Autotest running a lot faster. But then I noticed the stack traces weren’t being filtered any more. I like to keep their signal to noise ratio high by excluding the path through the various Rails libraries and Autotest itself.

It turns out that Ryan Davis modified the run_tests method in version 3.5.0 to write out the tests' results as they become available rather than buffering them until they are all complete.

This feeds back the results much sooner and admirably improves the user experience. It’s why I thought Autotest was running faster.

Unfortunately the change broke my filtering. I wasn’t too upset because it gave me an excuse to look through and savour Autotest’s beautiful code again. Happily I was able to resurrect the filtering — but at the expense of buffering the output.

I think I might know a way around this so we can have get-it-while-it’s-hot, high SNR output. While I investigate, here’s how to get filtered, buffered output.

In ~/.autotest:

Autotest.add_hook :run_command do |autotest|
  alias :original_putc :putc

  # Discard the unbuffered output
  def putc(obj)
  end
end

Autotest.add_hook :ran_command do |autotest|
  alias :whatever :putc   # So Ruby does not warn about discarding putc
  alias :putc     :original_putc

  autotest.results.delete_if { |result| result =~ %r{^.*/usr/local/lib/.*\\n?} }
  puts autotest.results.join
end

# Require redgreen after my :ran_command hook so mine runs first.
require 'autotest/redgreen'

You need to require any extensions that hook into :ran_command and write out to the console, such as redgreen, after our hook. This ensures the console output appears in the right order.

Andrew Stewart • 3 October 2007 • RailsRuby
You can reach me by email or on Twitter.