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.
Jim defined the basic rake methods [task, rule, file, directory, ...]
in the global ruby context -- much the same way you would define a
method in an irb session. When your Rakefile is loaded by the rake
system, it automatically has access to all these rake methods. Both
exist in the same global context.
Your code above is defining instance methods (foo and bar) within a
class. When you load a file in your test_acceptance method, that file
is being loaded in the global context NOT in the context of your test
case instance.
To do the latter ....
def test_acceptance
self.instance_eval IO.readlines('acceptance.rb')
end
A simpler example ...
ary = Array.new
ary.instance_eval "length" #=> 0
Hope this helps.
Blessings,
TwP
···
On 2/2/07, Jeff <cohen.jeff@gmail.com> 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.
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
The task method is defined by Rake at the top level, i.e. a normal method not within the scope of a class
def task(args, &block)
Rake::Task.define_task(args, &block)
end
Method defined in the top level context are available globally, which is why you can require 'rake' and then use the task method.
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
···
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.
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