Scripts run using load in "for" loop run out of order

Hi
I am new to ruby and like it so far.

I have an existing test harness to plug into and need to run a number of
scripts in a specific order.
I am using load in a "for loop" to run them. Unfortunately the scripts
get run out of order.

Below is my main script and my other scripts follow.

Files are:
test.rb
Tests/A-test.rb
Tests/B-test.rb
Tests/C-test.rb
Tests/D-test.rb

To simplify the question, I have created an array of the scripts I need
to run in the required order. But the output shows that the scripts run
in the following order D-test.rb, A-test.rb, C-test.rb and then
B-test.rb.

Somehow A gets run before C.

Is there any way to run the scripts in the correct order? And how come
it loops through the puts first and then the load?

Thanks in advance

#****** test.rb ********************
TOPDIR = File.join(File.dirname(__FILE__), '.')
$LOAD_PATH.unshift TOPDIR

require 'test/unit'
require 'test/unit/ui/console/testrunner'

Dir.chdir TOPDIR

testList = []

testList[0]="Tests/D-test.rb"
testList[1]="Tests/C-test.rb"
testList[2]="Tests/A-test.rb"
testList[3]="Tests/B-test.rb"

begin
  for i in 0 .. testList.length-1
    puts "i: #{i} testname: #{testList[i]}"
    load(testList[i])
  end
end

#************* A-test.rb ***************
class TC_One < Test::Unit::TestCase

  def setup
    puts
    puts "***********"
    puts "In A-test setup"
  end

  def test_one
    puts "In A-test.rb testcase one"
    sleep 1
  end

  def teardown
    puts "In A-test teardown"
    puts "***********"
    puts
  end
end

#************* B-test.rb ***************
class TC_Two < Test::Unit::TestCase

  def setup
    puts
    puts "***********"
    puts "In B-test setup"
  end

  def test_one
    puts "In B-test.rb testcase one"
    sleep 1
  end

  def teardown
    puts "In B-test teardown"
    puts "***********"
    puts
  end
end

#************* C-test.rb ***************
class TC_Three < Test::Unit::TestCase

  def setup
    puts
    puts "***********"
    puts "In C-test setup"
  end

  def test_one
    puts "In C-test.rb testcase one"
    sleep 1
  end

  def teardown
    puts "In C-test teardown"
    puts "***********"
    puts
  end
end
#************* D-test.rb ***************
class TC_Four < Test::Unit::TestCase

  def setup
    puts
    puts "***********"
    puts "In D-test setup"
  end

  def test_one
    puts "In D-test.rb testcase one"
    t = Time.now
    sleep 2
    puts t
  end

  def teardown
    puts "In D-test teardown"
    puts "***********"
    puts
  end
end
#************* Output ***************

Y:\ruby>test.rb
i: 0 testname: Tests/D-test.rb
i: 1 testname: Tests/C-test.rb
i: 2 testname: Tests/A-test.rb
i: 3 testname: Tests/B-test.rb
Loaded suite Y:/ruby/test
Started

···

***********
In D-test setup
In D-test.rb testcase one
Wed Jan 23 10:14:33 -0800 2008
In D-test teardown
***********

.
***********
In A-test setup
In A-test.rb testcase one
In A-test teardown
***********

.
***********
In C-test setup
In C-test.rb testcase one
In C-test teardown
***********

.
***********
In B-test setup
In B-test.rb testcase one
In B-test teardown
***********

.
Finished in 5.002 seconds.

4 tests, 0 assertions, 0 failures, 0 errors
--
Posted via http://www.ruby-forum.com/.

Hi
I am new to ruby and like it so far.

I have an existing test harness to plug into and need to run a number of
scripts in a specific order.
I am using load in a "for loop" to run them. Unfortunately the scripts
get run out of order.

To simplify the question, I have created an array of the scripts I need
to run in the required order. But the output shows that the scripts run
in the following order D-test.rb, A-test.rb, C-test.rb and then
B-test.rb.

Somehow A gets run before C.

in your code, your are not 'running' the test cases with your order
you're just loading Testcase declarations. All the collected test classes
are 'run' when your loop is finished.
The test-classes are running in alphabetical order ("TC_Four", "TC_One",
"TC_Three", "TC_Two")

And how come

it loops through the puts first and then the load?

it doesn't - it does perfectly the puts and then the load-statement but
since the load is only loading declarations you will see no output (like in
every other class declaration which is included in a ruby program).

-Thomas

···

On 23/01/2008, Fa Sidd <siddiqifh@yahoo.com> wrote:

--
Thomas Preymesser
thopre@gmail.com
thomas@thopre.com
Büro: 030 - 830 353 88
mobil: 0176 - 75 03 03 04
Privat: 030 - 49 78 37 06

Hi
I am new to ruby and like it so far.
...

First, since you are new to Ruby, some alternate ways to code your sample:

testList =

testList[0]="Tests/D-test.rb"
testList[1]="Tests/C-test.rb"
testList[2]="Tests/A-test.rb"
testList[3]="Tests/B-test.rb"

a) Append to the array instead of directly indexing:
    testList =
    testList << "Tests/D-test.rb"
    testList << "Tests/C-test.rb"
    testList << "Tests/A-test.rb"
    testList << "Tests/B-test.rb"

b) Directly initialize the literal array:
    testList = [
      "Tests/D-test.rb",
      "Tests/C-test.rb",
      "Tests/A-test.rb",
      "Tests/B-test.rb"
    ]

c) Initialize an array of words:
    testList = %w{
      Tests/D-test.rb
      Tests/C-test.rb
      Tests/A-test.rb
      Tests/B-test.rb
    }

begin
for i in 0 .. testList.length-1
   puts "i: #{i} testname: #{testList[i]}"
   load(testList[i])
end
end

a) Instead of explicit loop and indexing, iterate
    testList.each do |test|
      puts "testname: #{test}"
      load test
    end

b) If you still want the index too
    testList.each_with_index do |test, i|
      puts "#{i} \t #{test}"
      load test
    end

And, as to your question, perhaps you could try explicitly invoke the
TestRunner:

# load all of the test cases
Dir.glob("./Tests/*.rb").each do |tfile|
  require tfile
end

# run the test cases explicitly in order
[ TC_Four, TC_Three, TC_One, TC_Two ].each do |tclass|
  Test::Unit::UI::Console::TestRunner.run(tclass)
end

See "Test Runners" and "Test Suite":
http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html

···

On Jan 23, 2008 1:31 PM, Fa Sidd <siddiqifh@yahoo.com> wrote:

Thomas Preymesser wrote:

in your code, your are not 'running' the test cases with your order
you're just loading Testcase declarations. All the collected test
classes
are 'run' when your loop is finished.
The test-classes are running in alphabetical order ("TC_Four", "TC_One",
"TC_Three", "TC_Two")

Thanks for your response.

Is there a way I can run the scripts in the correct order in the loop?

···

--
Posted via http://www.ruby-forum.com/\.

And, as to your question, perhaps you could try explicitly invoke the
TestRunner:

...

See "Test Runners" and "Test Suite":
http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html

Oops, lost the last bit:
But, sorry that this doesn't yet work around not knowing the class
names just the file names.

To execute a test, you need to run it as follows:

  Test::Unit::UI::Console::TestRunner.run(test)

Try replacing everything after Dir.chdir TOPDIR with the following:

  Dir["Tests/*.rb"].each {|testfile| load "#{testfile}"}
  [TC_Four,TC_Three,TC_One,TC_Two,].each {|test|
Test::Unit::UI::Console::TestRunner.run(test) }

or if you want to name the files explicitly, you could do:

  testList = %w(Tests/A-test.rb Tests/B-test.rb Tests/C-test.rb Tests/
D-test.rb)
  testList.each {|testfile| load "#{testfile}"}
  [TC_Four,TC_Three,TC_One,TC_Two,].each {|test|
Test::Unit::UI::Console::TestRunner.run(test) }

This loads all the test classes first, then executes them in the order
you specify. Change the order of the classes in the second line if you
want to change the order of the tests.

···

On Jan 23, 1:32 pm, Fa Sidd <siddiq...@yahoo.com> wrote:

Thomas Preymesser wrote:
> in your code, your are not 'running' the test cases with your order
> you're just loading Testcase declarations. All the collected test
> classes
> are 'run' when your loop is finished.
> The test-classes are running in alphabetical order ("TC_Four", "TC_One",
> "TC_Three", "TC_Two")

Thanks for your response.

Is there a way I can run the scripts in the correct order in the loop?
--
Posted viahttp://www.ruby-forum.com/.

Maybe:

require 'test/unit/ui/console/testrunner'

# global array to hold the test classes as they are loaded
$tests =

# monkey patch to record the new subclasses as they are loaded
class Test::Unit::TestCase
  def self.inherited(subclass)
    $tests << subclass
  end
end

# load all the files
%w{
  Tests/D-test.rb
  Tests/C-test.rb
  Tests/A-test.rb
  Tests/B-test.rb
}.each do |tfile|
  require tfile
end

# run the test classes in the order they were loaded
$tests.each do |tclass|
  Test::Unit::UI::Console::TestRunner.run(tclass)
end

···

On Jan 24, 2008 6:06 PM, <brabuhr@gmail.com> wrote:

But, sorry that this doesn't yet work around not knowing the class
names just the file names.

zetetic wrote:

  testList = %w(Tests/A-test.rb Tests/B-test.rb Tests/C-test.rb Tests/
D-test.rb)
  testList.each {|testfile| load "#{testfile}"}
  [TC_Four,TC_Three,TC_One,TC_Two,].each {|test|
Test::Unit::UI::Console::TestRunner.run(test) }

This loads all the test classes first, then executes them in the order
you specify. Change the order of the classes in the second line if you
want to change the order of the tests.

I get the list of tests scripts from the test harness and do not know
the class names and execution order in advance.

Is there a better way to my tests, if I had just a list of test scripts
in order of execution

···

--
Posted via http://www.ruby-forum.com/\.

unknown wrote:

···

On Jan 24, 2008 6:06 PM, <brabuhr@gmail.com> wrote:

# monkey patch to record the new subclasses as they are loaded
class Test::Unit::TestCase
  def self.inherited(subclass)
    $tests << subclass
  end
end

# load all the files
%w{
  Tests/D-test.rb
  Tests/C-test.rb
  Tests/A-test.rb
  Tests/B-test.rb
}.each do |tfile|
  require tfile
end

# run the test classes in the order they were loaded
$tests.each do |tclass|
  Test::Unit::UI::Console::TestRunner.run(tclass)
end

This worked!

Not sure if replacing "load(testList[i])" with "`ruby #{testList[i]}`"
would have worked. I have global variables that I need to worry about

Thanks for the help everyone

Thanks.

--
Posted via http://www.ruby-forum.com/\.

Or, avoid the global with:

  class Test::Unit::TestCase
    class << self
      attr_reader :subclasses
      def inherited( subclass )
        (@subclasses||=) << subclass
      end
    end
  end

and then

  Test::Unit::TestCase.subclasses.each do |klass|
    ...
  end

···

On Jan 24, 4:24 pm, brab...@gmail.com wrote:

On Jan 24, 2008 6:06 PM, <brab...@gmail.com> wrote:

> But, sorry that this doesn't yet work around not knowing the class
> names just the file names.

Maybe:

require 'test/unit/ui/console/testrunner'

# global array to hold the test classes as they are loaded
$tests =

# monkey patch to record the new subclasses as they are loaded
class Test::Unit::TestCase
def self.inherited(subclass)
$tests << subclass
end
end

replace your "load(testList[i])"-line with "`ruby #{testList[i]}`"

-Thomas

···

On 24/01/2008, Fa Sidd <siddiqifh@yahoo.com> wrote:

zetetic wrote:
>
> testList = %w(Tests/A-test.rb Tests/B-test.rb Tests/C-test.rb Tests/
> D-test.rb)
> testList.each {|testfile| load "#{testfile}"}
> [TC_Four,TC_Three,TC_One,TC_Two,].each {|test|
> Test::Unit::UI::Console::TestRunner.run(test) }
>
> This loads all the test classes first, then executes them in the order
> you specify. Change the order of the classes in the second line if you
> want to change the order of the tests.

I get the list of tests scripts from the test harness and do not know
the class names and execution order in advance.

Is there a better way to my tests, if I had just a list of test scripts
in order of execution

--
Thomas Preymesser
thopre@gmail.com
thomas@thopre.com
Büro: 030 - 830 353 88
mobil: 0176 - 75 03 03 04
Privat: 030 - 49 78 37 06

Sweet! (or perhaps I should say: suite!)

···

On Jan 24, 6:06 pm, Phrogz <phr...@mac.com> wrote:

On Jan 24, 4:24 pm, brab...@gmail.com wrote:

> On Jan 24, 2008 6:06 PM, <brab...@gmail.com> wrote:

> > But, sorry that this doesn't yet work around not knowing the class
> > names just the file names.

> Maybe:

> require 'test/unit/ui/console/testrunner'

> # global array to hold the test classes as they are loaded
> $tests =

> # monkey patch to record the new subclasses as they are loaded
> class Test::Unit::TestCase
> def self.inherited(subclass)
> $tests << subclass
> end
> end

Or, avoid the global with:

  class Test::Unit::TestCase
    class << self
      attr_reader :subclasses
      def inherited( subclass )
        (@subclasses||=) << subclass
      end
    end
  end

and then

  Test::Unit::TestCase.subclasses.each do |klass|
    ...
  end

check out my dynaload gem, it abstracts this very pattern for objects, classses, and modules.

regards.

a @ http://codeforpeople.com/

···

On Jan 25, 2008, at 3:24 PM, zetetic wrote:

Sweet! (or perhaps I should say: suite!)

--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama