Tuesday, February 20, 2007

The ever evolving test suite

I've been working on a rather http://www2.blogger.com/img/gl.link.giflarge rails project and have watched my testing style evolve. And this next step, inspired by Jay Fields has really got me excited. Take a peek.

class Test::Unit::TestCase
class << self
def test(*names, &block)
test_name = :"test_#{names.join('_').gsub(/[^\w ]+/, '').gsub(/ +/, '_')}"
raise ArgumentError, "#{test_name} is already defined" if self.instance_methods.include?( test_name.to_s )
if block_given?
define_method( test_name, &block )
define_method( test_name) do
$stderr.puts "Incomplete test '#{names.join(', ')}' @ #{caller.last}"

What the above method does is allows for very "fast and loose" test definitions. For example, I can do the following:

class Foo < Test::Unit::TestCase
# This is a place holder test, and when ran will
# print a warning
test 'this will print a warning when the test runs'

# This is a genuine test
test 'this will assert true' do
assert true

# This is another genuine test, but I'm providing visually
# putting the test in another namespace
test :index => 'should render a list' do
assert_template 'list'

Ultimately, I'm extremely satisfied with how this works. My functional tests can have test definitions with a prefix of the action.

I have updated my Textmate so I can Run Focused Unit Tests, as well as having test highlighted like other keywords (alias, class, require, etc.)

No comments: