# Parameterized tests with test/unit

**URL:** <https://rubytalk.org/t/parameterized-tests-with-test-unit/12745>\
**Category:** ruby-talk\
**Created:** [24 July 2004 20:50 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745 "2004-07-24T20:50:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex2](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex2](https://rubytalk.org/u/Alex2)\
**Post date:** [24 July 2004 20:50 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/1 "2004-07-24T20:50:53Z")

</div>

Ruby is amazing... Try to do this in Java (it is possible, but not in so  
concise and readable way).

Speaking of tests, is there any known way to get test/unit report the  
results in XML, a la Ant Junit runner? Other markup easily convertible  
to HTML would do just as fine.

\<code\>

require 'test/unit'

class ClassUnderTest  
&nbsp;&nbsp;def square(i)  
&nbsp;&nbsp;&nbsp;&nbsp;i \* i  
&nbsp;&nbsp;end  
end

class ParaTest \< Test::Unit::TestCase  
&nbsp;&nbsp;# test methods are added dynamically to this class later in this file  
end

expectedResults = {-5 =\> 25, -1 =\> 1, 0 =\> 0, 1 =\> 1, 10 =\> 100,  
999999999 =\> 999999998000000001}

expectedResults.each\_pair do |parameter, expectedResult|  
&nbsp;&nbsp;ParaTest.module\_eval \<\<-EOL  
&nbsp;&nbsp;&nbsp;&nbsp;def testSquareOf#{parameter.to\_s.sub('-', 'Minus')}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal #{expectedResult},  
ClassUnderTest.new.square(#{parameter})  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;EOL  
end  
&nbsp;&nbsp;&nbsp;&nbsp;  
\</code\>

Best regards,  
Alexey Verkhovsky

---

<div class="post-metadata">

**Author:** ![Gavin\_Sinclair](https://avatars.discourse-cdn.com/v4/letter/g/db5fbb/32.png) [@Gavin\_Sinclair](https://rubytalk.org/u/Gavin_Sinclair)\
**Post date:** [25 July 2004 01:35 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/2 "2004-07-25T01:35:26Z")

</div>

> Ruby is amazing... Try to do this in Java (it is possible, but not in so  
> concise and readable way).

> [...]

> expectedResults = {-5 =\> 25, -1 =\> 1, 0 =\> 0, 1 =\> 1, 10 =\> 100,

999999999 =\>\> 999999998000000001}

> expectedResults.each\_pair do |parameter, expectedResult|  
> &nbsp;&nbsp;ParaTest.module\_eval \<\<-EOL  
> &nbsp;&nbsp;&nbsp;&nbsp;def testSquareOf#{parameter.to\_s.sub('-', 'Minus')}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal #{expectedResult},  
> ClassUnderTest.new.square(#{parameter})  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;EOL  
> end

Nifty, but I'd actually prefer to put all those tests in the one  
method in cases like that.

Cheers,  
Gavin

> **···**
>
> On Sunday, July 25, 2004, 6:50:53 AM, Alexey wrote:

---

<div class="post-metadata">

**Author:** ![Nathaniel\_Talbott1](https://avatars.discourse-cdn.com/v4/letter/n/a4c791/32.png) [@Nathaniel\_Talbott1](https://rubytalk.org/u/Nathaniel_Talbott1)\
**Post date:** [28 July 2004 23:20 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/3 "2004-07-28T23:20:25Z")

</div>

Not presently... although you could certainly write a runner to do so. It'd have a good chance of making its way in to the standard distribution if you did.

Nathaniel  
Terralien, Inc.

\<:((\>\<

> **···**
>
> On Jul 24, 2004, at 16:50, Alexey Verkhovsky wrote:
> 
> > Speaking of tests, is there any known way to get test/unit report the  
> > results in XML, a la Ant Junit runner? Other markup easily convertible  
> > to HTML would do just as fine.

---

<div class="post-metadata">

**Author:** ![Alex2](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex2](https://rubytalk.org/u/Alex2)\
**Post date:** [25 July 2004 03:26 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/4 "2004-07-25T03:26:15Z")

</div>

> Nifty,

"Nifty" is putting it mildly 🙂

> but I'd actually prefer to put all those tests in the one  
> method in cases like that.

For unit tests, such as my toy example, I would do the same.

In my situation (I try to use Ruby's test/unit for functional testing of  
batch jobs) putting each parameter into its own test, thus ensuring that  
if one assertion breaks other values are still tested, has its merit.

Best regards,  
Alex

> **···**
>
> On Sun, 2004-07-25 at 04:35, Gavin Sinclair wrote:

---

<div class="post-metadata">

**Author:** ![Alex2](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex2](https://rubytalk.org/u/Alex2)\
**Post date:** [29 July 2004 22:43 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/5 "2004-07-29T22:43:09Z")

</div>

I think I will try to do that.

Can you help me get the "specification" right?

I see it as follows:

ui/batch/testrunner.rb, which is a subclass of  
ui/console/testrunner.rb. It emits same output as console runner to  
stdout/stderr, but also writes one XML file for each test suite it has  
to run.

Naming convention and format of the XML is same as Ant JUnit runner (to  
reuse Ant formatter / stylesheets).

XML files are placed in the directory specified in a mandatory argument  
to the constructor.

Alternatives:

1. Output directory as an optional argument. I think, very few people  
really want to write test reports to the root of the project during the  
build, and therefore such default behavior would be counter-intuitive.  
Better to fail cleanly with a good error message.

2. Emit output as YAML, and give YAML -\> HTML conversion as part of the  
package. That would be more interesting, but harder. Is there a good  
YAML -\> HTML converter?

3. Can probably package this feature as a mixin to anything that  
subclasses TestRunnerUtils.

Brgds,  
Alex

> **···**
>
> On Thu, 2004-07-29 at 02:20, Nathaniel Talbott wrote:
> 
> > On Jul 24, 2004, at 16:50, Alexey Verkhovsky wrote:
> > 
> > \> Speaking of tests, is there any known way to get test/unit report the  
> > \> results in XML, a la Ant Junit runner? Other markup easily convertible  
> > \> to HTML would do just as fine.
> > 
> > Not presently... although you could certainly write a runner to do so.  
> > It'd have a good chance of making its way in to the standard  
> > distribution if you did.

---

<div class="post-metadata">

**Author:** ![Nathaniel\_Talbott1](https://avatars.discourse-cdn.com/v4/letter/n/a4c791/32.png) [@Nathaniel\_Talbott1](https://rubytalk.org/u/Nathaniel_Talbott1)\
**Post date:** [30 July 2004 00:12 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/6 "2004-07-30T00:12:39Z")

</div>

That sounds very reasonable; one possible alternative to subclassing would be to just create a delegating wrapper around the runner (since you want to run normally PLUS outputting XML). Just grab the mediator instance variable out of the runner (you'll have to use instance\_eval or somesuch as there's not currently a public method to get it) and attach your own listeners to it. The advantage to this is that you can theoretically wrap any mediator-using runner.

HTH,

Nathaniel  
Terralien, Inc.

\<:((\>\<

> **···**
>
> On Jul 29, 2004, at 18:43, Alexey Verkhovsky wrote:
> 
> > Can you help me get the "specification" right?
> > 
> > I see it as follows:
> > 
> > ui/batch/testrunner.rb, which is a subclass of  
> > ui/console/testrunner.rb. It emits same output as console runner to  
> > stdout/stderr, but also writes one XML file for each test suite it has  
> > to run.
> > 
> > Naming convention and format of the XML is same as Ant JUnit runner (to  
> > reuse Ant formatter / stylesheets).
> > 
> > XML files are placed in the directory specified in a mandatory argument  
> > to the constructor.

---

<div class="post-metadata">

**Author:** ![Alex2](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex2](https://rubytalk.org/u/Alex2)\
**Post date:** [30 July 2004 00:42 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/7 "2004-07-30T00:42:32Z")

</div>

If I understand you right, you mean some sort of decorator like this:

Test::Unit::TestReporter.new(:XML, 'build/reports', AllTests.suite)

Correct?

Alex

> **···**
>
> On Fri, 2004-07-30 at 03:12, Nathaniel Talbott wrote:
> 
> > one possible alternative to subclassing  
> > would be to just create a delegating wrapper around the runner (since  
> > you want to run normally PLUS outputting XML).

---

<div class="post-metadata">

**Author:** ![Nathaniel\_Talbott1](https://avatars.discourse-cdn.com/v4/letter/n/a4c791/32.png) [@Nathaniel\_Talbott1](https://rubytalk.org/u/Nathaniel_Talbott1)\
**Post date:** [30 July 2004 00:55 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/8 "2004-07-30T00:55:51Z")

</div>

I was thinking more like (untested):

&nbsp;&nbsp;&nbsp;class RunnerWrapper \< SimpleDelegate  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize(runner, output\_dir, format = :xml)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(runner)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add\_listeners(runner.instance\_eval{@mediator})  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def add\_listeners(mediator)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Collect the information you're interested in

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# When you receive the TestRunnerMediator::FINISHED event,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# write out the report  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

Does that help?

Nathaniel  
Terralien, Inc.

\<:((\>\<

> **···**
>
> On Jul 29, 2004, at 20:42, Alexey Verkhovsky wrote:
> 
> > On Fri, 2004-07-30 at 03:12, Nathaniel Talbott wrote:
> > 
> > > one possible alternative to subclassing  
> > > would be to just create a delegating wrapper around the runner (since  
> > > you want to run normally PLUS outputting XML).
> > 
> > If I understand you right, you mean some sort of decorator like this:
> > 
> > Test::Unit::TestReporter.new(:XML, 'build/reports', AllTests.suite)
> > 
> > Correct?

---

<div class="post-metadata">

**Author:** ![Alex2](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex2](https://rubytalk.org/u/Alex2)\
**Post date:** [30 July 2004 22:56 UTC](https://rubytalk.org/t/parameterized-tests-with-test-unit/12745/9 "2004-07-30T22:56:19Z")

</div>

Alas, this doesn't work because runner.@mediator is instantiated in  
runner.start, not in the constructor. So far I haven't found any way of  
safely getting mediator instance from the runner.

To move forward, I have added the following line in the  
TestRunner#start:

Index: testrunner.rb

> **···**
>
> On Fri, 2004-07-30 at 03:55, Nathaniel Talbott wrote:
> 
> > I was thinking more like (untested):
> > 
> > &nbsp;&nbsp;&nbsp;class RunnerWrapper \< SimpleDelegate  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize(runner, output\_dir, format = :xml)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(runner)
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add\_listeners(runner.instance\_eval{@mediator})  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> ===================================================================  
> RCS file: /src/ruby/lib/test/unit/ui/console/testrunner.rb,v  
> retrieving revision 1.7  
> diff -c -r1.7 testrunner.rb  
> \*\*\* testrunner.rb 21 Apr 2004 06:56:48 -0000 1.7  
> --- testrunner.rb 30 Jul 2004 22:48:30 -0000  
> \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> \*\*\* 38,43 \*\*\*\*  
> --- 38,44 ----  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def start  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setup\_mediator  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attach\_to\_mediator  
> + yield @mediator if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return start\_mediator  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;  
> Not sure, if this is the right approach, but it is quite obvious to me  
> that test runners need to be somehow refactored in order to support the  
> kind of decoration we are talking about.
> 
> By the way, I fully agree with this comment:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Perhaps there ought to be a TestRunner superclass? There  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# seems to be a decent amount of shared code between test  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# runners.
> 
> Please decide and tell me how it will be. Meantime, I go ahead with the  
> results formatter.
> 
> Best regards,  
> Alex
