I have a test case, based on the Test::Unit::TestCase. How does one pass
data to the test in such a way that the test can be run multiple times
with different input.
For example:
class TC_CreateOrder < Test::Unit::TestCase
def test_NewOrder
assert “order successful”
end
end
Now, I want to be able to generate a new order for various order types,
(TYPE1, TYPE2, TYPE3, etc.)
class TS_OrderTests
def self.suite
suite = Test::Unit::TestSuite.new
suite << TC_CreateOrder.suite # TYPE1 goes here
suite << TC_CreateOrder.suite # TYPE2 goes here
suite << TC_CreateOrder.suite # TYPE3 goes here
return suite
end
end
Test::Unit::UI::Console::TestRunner.run(TS_OrderTests)
Thanks in advance.
On Thu, Mar 29, 2007 at 06:23:14AM +0900, Matt B. wrote:
end
return suite
end
end
Test::Unit::UI::Console::TestRunner.run(TS_OrderTests)
If it’s only one test method, you can factor it out in the class:
class TC_CreateOrder < Test::Unit::TestCase
def do_test(t)
… process t
end
def test_type1
do_test(TYPE1)
end
def test_type2
do_test(TYPE2)
end
def test_type3
do_test(TYPE3)
end
end
Otherwise, how about:
class TC_CreateOrder1 < TC_CreateOrder
FIXTURE = TYPE1
end
class TC_CreateOrder2 < TC_CreateOrder
FIXTURE = TYPE2
end
class TC_CreateOrder3 < TC_CreateOrder
FIXTURE = TYPE3
end
(I’m not sure how you’d prevent the base test TC_CreateOrder being run)
Regards,
Brian.
Thanks Brian,
This would work ok if there was only one test method and only 3 types.
Now let’s say that I want to use this test technique multiple times,
with multiple test methods. And, the data input is over 100 items.
Duplicating this structure 100 times doesn’t seem tenable.
What I am really looking for is a data-driven test method, such that I
can use the same test case and pass it different data. However, for
test execution and measurement purposes, it is preferable to record
these as separate tests.
Brian C. wrote:
On Thu, Mar 29, 2007 at 06:23:14AM +0900, Matt B. wrote:
end
return suite
end
end
Test::Unit::UI::Console::TestRunner.run(TS_OrderTests)
If it’s only one test method, you can factor it out in the class:
class TC_CreateOrder < Test::Unit::TestCase
def do_test(t)
… process t
end
def test_type1
do_test(TYPE1)
end
def test_type2
do_test(TYPE2)
end
def test_type3
do_test(TYPE3)
end
end
Otherwise, how about:
class TC_CreateOrder1 < TC_CreateOrder
FIXTURE = TYPE1
end
class TC_CreateOrder2 < TC_CreateOrder
FIXTURE = TYPE2
end
class TC_CreateOrder3 < TC_CreateOrder
FIXTURE = TYPE3
end
(I’m not sure how you’d prevent the base test TC_CreateOrder being run)
Regards,
Brian.
On Fri, 30 Mar 2007, Matt B. wrote:
these as separate tests.
def setup
TEST_DATA = YAML.load(IO.read(ENV[‘TEST_DATA’])) # TEST_DATA is a
filename for
# yaml data
end
TEST_DATA=a.yml ruby test/a.rb
-a
On Fri, Mar 30, 2007 at 12:41:54AM +0900, Matt B. wrote:
This would work ok if there was only one test method and only 3 types.
Now let’s say that I want to use this test technique multiple times,
with multiple test methods. And, the data input is over 100 items.
Duplicating this structure 100 times doesn’t seem tenable.
…
end
But this was just an example; if this works then you can do it
dynamically.
How about something like:
$test_classes = []
fixtures = [TYPE1, TYPE2, TYPE3]
fixtures.each do |f|
klass = Class.new(TC_CreateOrder)
klass.const_set(:FIXTURE, f)
$test_classes << klass # to prevent garbage collection
end
You could write a private method in your test class which is called from
a
public test method which in turn gets the data from a YAML file or some
other data source.
e.g
require ‘test/unit’
class MyTest < Test::Unit::TestCase
def test_public
3.times { |i| _test_private(i) } # get your input data here before
calling private method
end
def _test_private(arg)
puts “Now testing with #{arg}”
assert(true)
end
private :_test_private
end
Loaded suite test
Started
Now testing with 0
Now testing with 1
Now testing with 2
Thanks to everyone who posted responses. Through a combination of your
feedback and experimentation, here is the solution I came up with:
class TC_CreateOrder < Test::Unit::TestCase
def test_NewOrder
orderTypeList = File.open(‘orders.yaml’) { |yf| YAML::load(yf) }
orderTypeList.each { |type|
# perform the test
assert “order successful”
@_result.add_run
end
end
The trick was the last line “@_result.add_run”. By adding this line,
each time through the loop increments the test count such that each
order is a separate test case.
Nasir K. wrote:
You could write a private method in your test class which is called from
a
public test method which in turn gets the data from a YAML file or some
other data source.
e.g
require ‘test/unit’
class MyTest < Test::Unit::TestCase
def test_public
3.times { |i| _test_private(i) } # get your input data here before
calling private method
end
def _test_private(arg)
puts “Now testing with #{arg}”
assert(true)
end
private :_test_private
end
Loaded suite test
Started
Now testing with 0
Now testing with 1
Now testing with 2