Autotest without Rails
Autotest is a gem (well, technically ZenTest is a gem that includes autotest). But seriously, autotest is a gem! I can’t write code without it anymore. It has become my coding security blanket.
I started going through withdrawal last night while I was working on a Ruby library because autotest doesn’t work out of the box with plain ol’ Ruby projects. It assumes you’re using one of the Ruby web frameworks.
Here’s how to remedy that.
Aizatto shows us how to use autotest with your Rails plugins and RSpec. That’s a great start, but unfortunately, not all of my projects use RSpec (yet), and not all of them are Rails plugins.
To make autotest work with Test::Unit, we need to tell it how to map files to their tests. Here is a simple mapping that maps each ruby file in lib/ to the a corresponding test test/*_test.rb. For example, lib/foo/bar.rb would map to to a test in test/foo/bar_test.rb.
# autotest/testunit.rb
require 'autotest'
class Autotest::Testunit < Autotest
def initialize # :nodoc:
super
@exceptions = /^\.\/(?:config|doc|log|tmp|website)/
@test_mappings = {
%r%^test/.*\.rb$% => proc { |filename, _|
filename
},
%r%^lib/(.*)\.rb$% => proc { |_, m|
["test/#{m[1]}_test.rb"]
},
%r%^test/test_helper.rb$% => proc {
files_matching %r%^test/.*_test\.rb$%
},
}
end
# Given the string filename as the path, determine
# the corresponding tests for it, in an array.
def tests_for_file(filename)
super.select { |f| @files.has_key? f }
end
end
We have the mapping, now all we need to do is tell autotest about it.
# autotest/discover.rb
require File.dirname(__FILE__) + '/testunit'
Autotest.add_discovery { "testunit" }
Throw both of those files into a autotest/ directory in your plain ol’ Ruby project and autotest should just work for you.
Extra credit: Make it work with RSpec on plain ol’ Ruby projects.
6 comments
Won’t think break autotest for rails projects? Do you change your
~/.autotest/files when you switch between the different projects?Tammer,
No, you put those files inside your project, not your
~/.autotestfile.Theoretically, you could put them in your autotest file, but you’d have to modify it a bit:
Autotest.add_discovery do "testunit" if !File.exist? 'config/environment.rb' && File.exist? 'test' endThat will only add the testunit support if the project has a test directory and it doesn’t have config/environment.rb.
I just run autotest inside brand new Ruby projects w/ nothing but lib and spec directories. It just works.
Ummmm I am a beginner ( actually just reading more about it ) and this doesnt really make sense for me. Can I have a sort of references for this, maybe some other examples ?
Thanks
“I started going through withdrawal last night while I was working on a Ruby library because autotest doesn’t work out of the box with plain ol’ Ruby projects.”
Huh?!? Yes it does. I use it on ALL of my projects, almost all without a .autotest file.
Everything you have in the code example is unnecessary. (and probably broken against the latest autotest).
Thanks for the post! This worked great for my non-Rails project that has a custom directory structure (code is in lib/ while tests are either in test/unit or test/functional – and all tests look like foo_test.rb).
I just had to do a tiny bit of tweaking (to @test_mapping) and your code worked perfectly on ZenTest 3.10.0.
That said, if there is another more standard way to achieve this without patching Autotest classes (perhaps via .autotest), I’d love to know about it.
Speak your mind: