Autotest, Rails, and testing the lib folder

by admin on August 16, 2010 · 1 comment

I finally installed autotest for my Rails development – if you haven’t heard about it, it might just be the thing that gets you into TATFT mode: you edit a file, and the relevant tests automatically run.  It’s like continuous integration for your development machine, basically, and I’m amazed at how much time it saves by eliminating seemingly tiny operations like remembering to launch the test runner.

The thing was though, that I wanted a certain setup for my lib folder and accompanying tests.  Before things get to the plugin/gem phase, most of my library code that’s outside of the models and controllers usually sits in lib until I figure out what I want to do with it.

To test these things, I prefer to have a separate test folder instead of using test/unit – for one thing, I usually don’t have ActiveRecord involved in these modules, so I don’t need the fixtures to run.

Getting rake to handle the lib tests is pretty simple, thanks to this this tip from Stack Overflow:


namespace :test do

desc "Test lib source"

Rake::TestTask.new(:lib) do |t|

t.libs << "test"

t.pattern = 'test/lib/**/*_test.rb'

t.verbose = true

end

end

So great, now I can run ‘rake test:lib’ and I’m golden, but that doesn’t give me automatic goodness.

For autotest to do the same thing, you need to add some mappings to your .autotest file in the root of the project:

Autotest.add_hook :initialize do |at|
  %w{.git .svn .hg .DS_Store vendor tmp log doc}.each do |exception|
    at.add_exception(exception)
  end

  at.remove_mapping(/^lib\/.*\.rb$/)
  at.add_mapping(%r%^lib/(.*).rb%) do |filename, m|
    ["test/lib/#{m[1]}_test.rb"]
  end

  at.add_mapping(%r%^test/lib/.*\.rb$%) {|filename, _| filename}

end

The remove_mapping call is the key to making this all work: when autotest runs against a Rails app, mappings are already in place thanks to the autotest-rails gem.  That gem, however, has its own opinions for how lib files get run, and by default it’ll run tests in test/unit, which isn’t what I want.  If you don’t remove that mapping, your mapping won’t check against any .rb files in lib, and you’ll spend a few hours going insane.

Thanks go out to Brandon Keepers for some sample .autotest setups that I was able to work from!

Leave a Comment

{ 1 trackback }

Previous post:

Next post: