Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Ruby (http://www.velocityreviews.com/forums/f66-ruby.html)
-   -   passing data to tests with test/unit (http://www.velocityreviews.com/forums/t839436-passing-data-to-tests-with-test-unit.html)

Matt Berney 03-28-2007 09:23 PM

passing data to tests with test/unit
 
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_OrderTe sts)

Thanks in advance.

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


Brian Candler 03-29-2007 05:12 AM

Re: passing data to tests with test/unit
 
On Thu, Mar 29, 2007 at 06:23:14AM +0900, Matt Berney wrote:
> 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_OrderTe sts)


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.


Matt Berney 03-29-2007 03:41 PM

Re: passing data to tests with test/unit
 
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 Candler wrote:
> On Thu, Mar 29, 2007 at 06:23:14AM +0900, Matt Berney wrote:
>> end
>> return suite
>> end
>> end
>>
>> Test::Unit::UI::Console::TestRunner.run(TS_OrderTe sts)

>
> 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.



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


ara.t.howard@noaa.gov 03-29-2007 04:51 PM

Re: passing data to tests with test/unit
 
On Fri, 30 Mar 2007, Matt Berney wrote:

> 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.
>



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
--
be kind whenever possible... it is always possible.
- the dalai lama


Brian Candler 03-29-2007 07:09 PM

Re: passing data to tests with test/unit
 
On Fri, Mar 30, 2007 at 12:41:54AM +0900, Matt Berney 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.

...
> > class TC_CreateOrder1 < TC_CreateOrder
> > FIXTURE = TYPE1
> > end
> >
> > class TC_CreateOrder2 < TC_CreateOrder
> > FIXTURE = TYPE2
> > end
> >
> > class TC_CreateOrder3 < TC_CreateOrder
> > FIXTURE = TYPE3
> > 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


Matt Berney 03-30-2007 03:43 PM

Re: passing data to tests with test/unit
 
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 Khan 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
>
> - nasir



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



All times are GMT. The time now is 07:43 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.