Using define_method to create a dynamic test-unit case also runs placeholder value

255 views Asked by At

So, I'm using the parrallel gem to create a set of test cases that can run concurrently.

I have the test case names specified in a yaml and through the parallel process each test case name assigned to the global var $t.

I then use define_method to define the unique method name for each test-unit test case. (Without a unique method name test-unit will error with a test case was redefined error.

What I'm seeing is that each test case name is being parsed through and the tests are running, returning the appropriate test-unit results - the tests run smoothly and end correctly.

However at the end of the test run I'm presented with an undefined method error on testcase, which is the define_method placeholder variable i.e. define_method("testcase").

I don't understand why it's trying to run the placeholder variable - and I don't know how to stop it from doing that.

Here's the error.

: undefined method `testcase' for TestCase:Class (NoMethodError)
    from build/sanity.rb:16:in `block (2 levels) in <main>'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:386:in `call'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:386:in `call_with_index'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:315:in `process_incoming_jobs'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:298:in `block in worker'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:291:in `fork'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:291:in `worker'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:279:in `block in create_workers'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:278:in `each'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:278:in `create_workers'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:242:in `work_in_processes'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:114:in `map'
    from /Users/[user]/.rvm/gems/ruby-2.1.2/gems/parallel-1.0.0/lib/parallel.rb:81:in `each'
    from build/sanity.rb:13:in `block in <main>'

Here's the relevant ruby code.

Parallel.each($testcases, :in_processes=>26) { |m|
        $t = m["testName"]

        class TestCase < Test::Unit::TestCase
            define_method("testcase") do
                send($t)
            end

            testcase("test_#{$t}")
        end
    }

Any insight into what is actually happening here and on fundamental concepts I may be missing is appreciated as well.

1

There are 1 answers

0
YoDK On BEST ANSWER

I ended up removing testcase("test_#{$t}") and put the variable string directly into define_method

Parallel.each($testcases, :in_processes=>26) { |m|
    $t = m["testName"]

    class TestCase < Test::Unit::TestCase
        define_method("test_#{$t}") do
            send($t)
        end
    end
}

I have no idea why this works. Any insight would be appreciated.