Bare bones ruby unit testing

This morning I spent a happy hour exploring a little of ruby's Test::Unit::TestCase. I started with this:
require 'test/unit'

class MyTest < Test::Unit::TestCase

  def test_one_plus_one_equals_two
    assert_equal 2, 1+1.1
  end

end
I wanted to see how little I needed to write my own, super-minimal implementation of Test::Unit::TestCase...
require 'test/unit'

class MyTest < MyTestCase

  def test_one_plus_one_equals_two
    assert_equal 2, 1+1.1
  end

end
After 204 traffic lights in cyber-dojo I ended up with this...
require 'assertion_failed_error'

class MyTestCase

  def self.test_names
    public_instance_methods.select{|name| name =~ /^test_/}
  end
  
  def assert_equal( expected, actual )
    message = 
      "#{expected.inspect} expected but was\n" +
      "#{actual.inspect}\n"
    assert_block(message) { expected == actual }
  end

  def assert_block( message )
    if (! yield)
      raise AssertionFailedError.new(message.to_s)
    end
  end

end

at_exit do
  ::ObjectSpace.each_object(Class) do |klass|
    if (klass < MyTestCase)
      klass.test_names.each do |method_name| 
        begin
          klass.new.send method_name
        rescue AssertionFailedError => error
          print "#{klass.name}:#{method_name}:\n" +
                "#{error.message}"
        end
      end
    end
  end
end
class AssertionFailedError < RuntimeError; end
which allowed me write...
require 'my_test_case'

class MyTest < MyTestCase

  def test_one_plus_one_equals_two
    assert_equal 2, 1+1.1
  end

end
and finally, I added this...
class MyTestCase
  ...
  def self.test( name, &block )
    define_method("test_#{name}".to_sym, &block)
  end
  ...
end
which allowed me to rewrite the test as...
require 'my_test_case'

class MyTest < MyTestCase

  test "1+1 == 2" do
    assert_equal 2, 1+1.1
  end

end
Fun :-)