Dynamically add a method to a TestCase

Hi,

I'm experimenting with the dynamic features of ruby to add methods to
a TestCase. Here is my test script:

require 'watir'
require 'test/unit'

class MyTest < Test::Unit::TestCase
end

for num in ["a","b","c"]
    MyTest.send(:define_method,"test_" + num) {
        assert(false,"->"+num)
    }
end

It works fine so far, but all asserts display "->c" as error message.
I don't understand why! Any hint? How to fix it?

regards,
Achim

That's exactly what you're telling assert to do. Method definition is
something like:

assert(expression, error_message = nil)

What exactly are you wanting to do?

Jason

···

On Jan 2, 2008 1:55 PM, Achim Domma <domma@procoders.net> wrote:

Hi,

I'm experimenting with the dynamic features of ruby to add methods to
a TestCase. Here is my test script:

require 'watir'
require 'test/unit'

class MyTest < Test::Unit::TestCase
end

for num in ["a","b","c"]
   MyTest.send(:define_method,"test_" + num) {
       assert(false,"->"+num)
   }
end

It works fine so far, but all asserts display "->c" as error message.
I don't understand why! Any hint? How to fix it?

regards,
Achim

Achim Domma wrote:

Hi,

I'm experimenting with the dynamic features of ruby to add methods to
a TestCase. Here is my test script:

require 'watir'
require 'test/unit'

class MyTest < Test::Unit::TestCase
end

for num in ["a","b","c"]
    MyTest.send(:define_method,"test_" + num) {
        assert(false,"->"+num)
    }
end

It works fine so far, but all asserts display "->c" as error message.
I don't understand why! Any hint? How to fix it?

It's the way the 'for' construct scopes the 'num' variable. All three method definition blocks are seeing 'num' in the same scope, so they all get the last assigned value, "c".

Try this:

   procs =
   for num in ["a","b","c"]
   #["a","b","c"].each do |num|
       procs << proc {
           num
       }
   end

   procs.each do |pr|
     puts pr.call
   end

That prints three 'c's.

Now uncomment the 'each' line and comment out the 'for' line, and you'll see the scope difference!

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

One way to fix it is to use eval rather then send:

<code>
require 'test/unit'

class MyTest < Test::Unit::TestCase
    for ch in %w[a b c]
       eval %[define_method("test_#{ch}") { assert(false, "->#{ch}") }]
    end
end
</code>

Regards, Morton

···

On Jan 2, 2008, at 1:55 PM, Achim Domma wrote:

Hi,

I'm experimenting with the dynamic features of ruby to add methods to
a TestCase. Here is my test script:

require 'watir'
require 'test/unit'

class MyTest < Test::Unit::TestCase
end

for num in ["a","b","c"]
    MyTest.send(:define_method,"test_" + num) {
        assert(false,"->"+num)
    }
end

It works fine so far, but all asserts display "->c" as error message.
I don't understand why! Any hint? How to fix it?

Dah crap, excuse my previous email. I need to work on my reading
comprehension.

That is odd. I would assume that a puts there would always say "c", though
it can't hurt to try.

Jason

···

On Jan 2, 2008 2:06 PM, Jason Roelofs <jameskilton@gmail.com> wrote:

On Jan 2, 2008 1:55 PM, Achim Domma <domma@procoders.net> wrote:

> Hi,
>
> I'm experimenting with the dynamic features of ruby to add methods to
> a TestCase. Here is my test script:
>
> require 'watir'
> require 'test/unit'
>
> class MyTest < Test::Unit::TestCase
> end
>
> for num in ["a","b","c"]
> MyTest.send(:define_method,"test_" + num) {
> assert(false,"->"+num)
> }
> end
>
> It works fine so far, but all asserts display "->c" as error message.
> I don't understand why! Any hint? How to fix it?
>
> regards,
> Achim
>

That's exactly what you're telling assert to do. Method definition is
something like:

assert(expression, error_message = nil)

What exactly are you wanting to do?

Jason