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

On 23/01/2008, Fa Sidd [email protected] wrote:

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


Thomas P.
[email protected]
[email protected]
Büro: 030 - 830 353 88
mobil: 0176 - 75 03 03 04
Privat: 030 - 49 78 37 06

http://www.thopre.com/

Thomas P. 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?

On Jan 23, 1:32 pm, Fa Sidd [email protected] wrote:

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

Posted viahttp://www.ruby-forum.com/.

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.

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

On Jan 23, 2008 1:31 PM, Fa Sidd [email protected] wrote:

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 24/01/2008, Fa Sidd [email protected] wrote:

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

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

-Thomas


Thomas P.
[email protected]
[email protected]
Büro: 030 - 830 353 88
mobil: 0176 - 75 03 03 04
Privat: 030 - 49 78 37 06

http://www.thopre.com/

On Jan 24, 2008 6:06 PM, [email protected] 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

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

unknown wrote:

On Jan 24, 2008 6:06 PM, [email protected] 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.

On Jan 24, 4:24 pm, [email protected] wrote:

$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

On Jan 24, 6:06 pm, Phrogz [email protected] wrote:

end
end

and then

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

end

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

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.

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

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

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

regards.

a @ http://codeforpeople.com/