Daniel Schierbeck
2/3/2007 12:42:00 AM
On Sat, 2007-02-03 at 07:05 +0900, Jeff wrote:
> I'm looking into a way to let business users write functional tests in
> rails, and I wanted to have my functional test file load an external
> file to supply the body of a method. It occurs to me that Rake must
> have solved a similar problem, but I can't quite figure out how Jim
> did it.
>
> What I want to write is something like this:
>
> class MyTests < Test::Unit::TestCase
>
> # typical setup and teardown here
>
> # a test method to "wrap" an external ruby file
>
> def test_acceptance
> load 'acceptance.rb' # load file written by business user
> end
>
> def foo
> end
>
> def bar
> end
>
> end
>
> I admit it didn't look right when I wrote it. I had hoped that the
> code in acceptance.rb could be bare Ruby code. in other words, it
> would look like and feel top-level Ruby, but could call foo and bar
> because it's really in the midst of the test_acceptance method.
>
> So I conclude that load() starts a new scope. I guess I could add my
> methods to Object and/or Module to get them to be seen by the external
> file, but I don't think that does any good either.
>
> But Rake does something similar, right? I think it defines the task()
> method, etc. and you can refer to them in "bare" ruby code in your
> rake file.
>
> What glue is being used in Rake that I'm missing?
>
> Thanks!
> Jeff
I think I get your point. This is what I'd do, though:
module TestContainer
class << self
def tests
@tests ||= {}
end
def define_test(name, &body)
@tests[name] = body
end
end
end
module Kernel
def test(name, &body)
TestContainer.define_test(name, &body)
end
end
Then you can just go and do:
# foo_test.rb
test :foo do
assert_equal 4, 2 * 2
end
And then, in your test file:
require 'foo_test'
class MyTest < Test::Unit::TestCase
TestContainer.tests.each do |name, body|
define_method("test_#{name}", &body)
end
end
Cheers,
Daniel