passing data to tests with test/unit

Discussion in 'Ruby' started by Matt Berney, Mar 28, 2007.

  1. Matt Berney

    Matt Berney Guest

    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.

    --
    Posted via http://www.ruby-forum.com/.
    Matt Berney, Mar 28, 2007
    #1
    1. Advertising

  2. 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_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.
    Brian Candler, Mar 29, 2007
    #2
    1. Advertising

  3. Matt Berney

    Matt Berney Guest

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



    --
    Posted via http://www.ruby-forum.com/.
    Matt Berney, Mar 29, 2007
    #3
  4. Matt Berney

    Guest

    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
    , Mar 29, 2007
    #4
  5. 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
    Brian Candler, Mar 29, 2007
    #5
  6. Matt Berney

    Matt Berney Guest

    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/.
    Matt Berney, Mar 30, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Finney

    Iterating over test data in unit tests

    Ben Finney, Dec 6, 2005, in forum: Python
    Replies:
    6
    Views:
    281
    Scott David Daniels
    Dec 6, 2005
  2. Alexey Verkhovsky

    Parameterized tests with test/unit

    Alexey Verkhovsky, Jul 24, 2004, in forum: Ruby
    Replies:
    8
    Views:
    314
    Alexey Verkhovsky
    Jul 30, 2004
  3. Simon Strandgaard
    Replies:
    14
    Views:
    176
    Nathaniel Talbott
    Aug 16, 2004
  4. Raphael Bauduin
    Replies:
    6
    Views:
    96
    Nathaniel Talbott
    Feb 2, 2005
  5. timr
    Replies:
    2
    Views:
    154
Loading...

Share This Page