# Test::Unit - same test, different "args"

**URL:** <https://rubytalk.org/t/test-unit-same-test-different-args/52461>\
**Category:** ruby-talk\
**Created:** [23 March 2009 20:47 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461 "2009-03-23T20:47:01Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [23 March 2009 20:47 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/1 "2009-03-23T20:47:01Z")

</div>

I need to run the same unit test case more than 10 times (around 150  
tests in the test case), with 2-3 parameters changed each time.

For instance, if I had unit tests to examine a "Person", with a  
required parameter "name" - let's say I want to run the same  
Test::Unit::TestCase on 10 different people, with different names but  
everything else the same. All test cases run the same code, just with  
the one (or two) parameters tweaked.

Let's say I have 150 tests for a Person - I'd rather not end up with  
1500 tests, each of the 150 tests exactly duplicated for a different  
"name".

I'll have a hierarchy of tests cases, in suites, which may help

Is there some way to:  
1) set a global variable in the "parent" test suite that the children  
see? Seems like the answer to this is no  
2) Pass an arg to the test case as a whole? Don't see anyway to do  
this in the docs  
3) Do something else that will keep this test code compliant with DRY?

What's the right approach here?

---

<div class="post-metadata">

**Author:** ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)\
**Post date:** [23 March 2009 21:36 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/2 "2009-03-23T21:36:57Z")

</div>

Luke St.Clair wrote:

> I need to run the same unit test case more than 10 times (around 150  
> tests in the test case), with 2-3 parameters changed each time.
> 
> For instance, if I had unit tests to examine a "Person", with a  
> required parameter "name" - let's say I want to run the same  
> Test::Unit::TestCase on 10 different people, with different names but  
> everything else the same. All test cases run the same code, just with  
> the one (or two) parameters tweaked.

Put all the test\_ methods into a module, and include it into 10 different suites:

class ATest \< Test::Unit::TestCase; include Suite; setup; @me = 'a'; end; end  
class BTest \< Test::Unit::TestCase; include Suite; setup; @me = 'b'; end; end  
class CTest \< Test::Unit::TestCase; include Suite; setup; @me = 'c'; end; end  
class DTest \< Test::Unit::TestCase; include Suite; setup; @me = 'd'; end; end

there might be a less effusive way, but the Abstract Test Pattern is very important to learn, so this is a good start...

> What's the right approach here?

Abstract Test is best to match an important class hierarchy in your code. Otherwise, the question arises are you missing an abstraction? Could you simplify something else, and test fewer permutations?

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [23 March 2009 22:02 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/3 "2009-03-23T22:02:17Z")

</div>

Luke St.Clair wrote:

> Is there some way to:  
> 1) set a global variable in the "parent" test suite that the children  
> see? Seems like the answer to this is no

Shoulda sits on top of Test::Unit and may be helpful. Something like  
this:

class MyTest \< Test::Unit::TestCase  
&nbsp;&nbsp;context "top level" do  
&nbsp;&nbsp;&nbsp;&nbsp;setup do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@stuff = ...  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;should "test something at top level" do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal 123, @stuff.size  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;context "inner level" do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setup do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@more\_stuff = ...  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;should "test more" do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal @stuff.size, @more\_stuff.size  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

See:

> **[thoughtbot case studies featuring design and development projects for...](https://thoughtbot.com/case-studies)**
>
> Check out some thoughtbot case studies featuring design and development projects for websites, mobile and web applications across HealthTech, EdTech, FinTech B2B and B2C.

[http://mtnwestrubyconf2008.confreaks.com/12saleh.html](http://mtnwestrubyconf2008.confreaks.com/12saleh.html)  
[http://tammersaleh.com/system/assets/bdd\_with\_shoulda.pdf](http://tammersaleh.com/system/assets/bdd_with_shoulda.pdf)

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [24 March 2009 19:36 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/4 "2009-03-24T19:36:59Z")

</div>

I think this is what I'm going to go with - I'll have a test case for  
each possible param value (there are about 10), and each one will set  
a few additional global variables. Then, each test case will include  
the same module, which will call functions with params set by the  
global variables.

Seems to be very DRY, as long as the set of param values is small (it  
is in this case, and should stay small in the future).

Thanks -

> **···**
>
> On Mar 23, 2:38 pm, Phlip \<phlip2...@gmail.com\> wrote:
> 
> > Luke St.Clair wrote:  
> > \> I need to run the same unit test case more than 10 times (around 150  
> > \> tests in the test case), with 2-3 parameters changed each time.
> > 
> > \> For instance, if I had unit tests to examine a "Person", with a  
> > \> required parameter "name" - let's say I want to run the same  
> > \> Test::Unit::TestCase on 10 different people, with different names but  
> > \> everything else the same. All test cases run the same code, just with  
> > \> the one (or two) parameters tweaked.
> > 
> > Put all the test\_ methods into a module, and include it into 10 different suites:
> > 
> > class ATest \< Test::Unit::TestCase; include Suite; setup; @me = 'a'; end; end  
> > class BTest \< Test::Unit::TestCase; include Suite; setup; @me = 'b'; end; end  
> > class CTest \< Test::Unit::TestCase; include Suite; setup; @me = 'c'; end; end  
> > class DTest \< Test::Unit::TestCase; include Suite; setup; @me = 'd'; end; end
> > 
> > there might be a less effusive way, but the Abstract Test Pattern is very  
> > important to learn, so this is a good start...
> > 
> > \> What's the right approach here?
> > 
> > Abstract Test is best to match an important class hierarchy in your code.  
> > Otherwise, the question arises are you missing an abstraction? Could you  
> > simplify something else, and test fewer permutations?

---

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [24 March 2009 19:51 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/5 "2009-03-24T19:51:52Z")

</div>

This seems incredibly useful - unfortunately, I can't use shoulda.

> **···**
>
> On Mar 23, 3:02 pm, Brian Candler \<b.cand...@pobox.com\> wrote:
> 
> > Luke St.Clair wrote:  
> > \> Is there some way to:  
> > \> 1) set a global variable in the "parent" test suite that the children  
> > \> see? Seems like the answer to this is no
> > 
> > Shoulda sits on top of Test::Unit and may be helpful. Something like  
> > this:
> > 
> > class MyTest \< Test::Unit::TestCase  
> > context "top level" do  
> > setup do  
> > @stuff = ...  
> > end
> > 
> > ```
> > should &quot;test something at top level&quot; do
> > assert\_equal 123, @stuff\.size
> > end
> > 
> > context &quot;inner level&quot; do
> > setup do
> > @more\_stuff = \.\.\.
> > end
> > 
> > should &quot;test more&quot; do
> > assert\_equal @stuff\.size, @more\_stuff\.size
> > end
> > end
> > 
> > ```
> > 
> > end  
> > end

---

<div class="post-metadata">

**Author:** ![Brian\_Candler](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@Brian\_Candler](https://rubytalk.org/u/Brian_Candler)\
**Post date:** [24 March 2009 23:20 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/6 "2009-03-24T23:20:27Z")

</div>

Luke St.Clair wrote:

> This seems incredibly useful - unfortunately, I can't use shoulda.

Out of interest, why not? Policy constraint?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [25 March 2009 23:26 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/7 "2009-03-25T23:26:47Z")

</div>

The biggest issue I'm running into right now is not having startup(),  
or code that runs once per test suite, not once per test case.

Is this in test::unit yet?

> **···**
>
> On Mar 24, 12:39 pm, "Luke St.Clair" \<secureb...@gmail.com\> wrote:
> 
> > I think this is what I'm going to go with - I'll have a test case for  
> > each possible param value (there are about 10), and each one will set  
> > a few additional global variables. Then, each test case will include  
> > the same module, which will call functions with params set by the  
> > global variables.

---

<div class="post-metadata">

**Author:** ![Kouhei\_Sutou1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/kouhei_sutou1/32/2034_2.png) [@Kouhei\_Sutou1](https://rubytalk.org/u/Kouhei_Sutou1)\
**Post date:** [26 March 2009 12:37 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/8 "2009-03-26T12:37:10Z")

</div>

Hi,

In \<03af6afa-9ba0-4124-bc2b-185f907c24f7@a5g2000pre.googlegroups.com\>  
&nbsp;&nbsp;"Re: Test::Unit - same test, different "args"" on Wed, 25 Mar 2009 04:51:52 +0900,

> > Luke St.Clair wrote:  
> > \> Is there some way to:  
> > \> 1) set a global variable in the "parent" test suite that the children  
> > \> see? Seems like the answer to this is no
> > 
> > Shoulda sits on top of Test::Unit and may be helpful. Something like  
> > this:
> > 
> > class MyTest \< Test::Unit::TestCase  
> > context "top level" do  
> > setup do  
> > @stuff = ...  
> > end
> > 
> > ```
> > should &quot;test something at top level&quot; do
> > assert\_equal 123, @stuff\.size
> > end
> > 
> > context &quot;inner level&quot; do
> > setup do
> > @more\_stuff = \.\.\.
> > end
> > 
> > should &quot;test more&quot; do
> > assert\_equal @stuff\.size, @more\_stuff\.size
> > end
> > end
> > 
> > ```
> > 
> > end  
> > end
> 
> This seems incredibly useful - unfortunately, I can't use shoulda.

Test::Unit 2.x also supports that usage with natural Ruby  
syntax:

&nbsp;&nbsp;# From [http://test-unit.rubyforge.org/svn/trunk/sample/test\_user.rb](http://test-unit.rubyforge.org/svn/trunk/sample/test_user.rb)

&nbsp;&nbsp;class UserTest \< Test::Unit::TestCase  
&nbsp;&nbsp;&nbsp;&nbsp;def setup  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@user = "me"  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;def test\_full\_name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal("me", @user)  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;class ProfileTest \< UserTest  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setup  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def setup\_profile  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@user += ": profile"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_has\_profile  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_match(/: profile/, @user)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

Thanks,

> **···**
>
> "Luke St.Clair" \<secureboot@gmail.com\> wrote:
> 
> > On Mar 23, 3:02 pm, Brian Candler \<b.cand...@pobox.com\> wrote:
> 
> --  
> kou

---

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [25 March 2009 23:26 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/9 "2009-03-25T23:26:47Z")

</div>

Basically, yes.

> **···**
>
> On Mar 24, 4:20 pm, Brian Candler \<b.cand...@pobox.com\> wrote:
> 
> > Luke St.Clair wrote:  
> > \> This seems incredibly useful - unfortunately, I can't use shoulda.
> > 
> > Out of interest, why not? Policy constraint?  
> > --  
> > Posted viahttp://www.ruby-forum.com/.

---

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [25 March 2009 23:36 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/10 "2009-03-25T23:36:45Z")

</div>

Better yet, is there some way to get around this?

Right now, I have like 8 test suite files, which do something like:

initialize\_things(foo)

class MyTester \< Test::Unit::TestCase  
&nbsp;&nbsp;include cases1  
&nbsp;&nbsp;include cases2  
end

This works fine if I run the file directly, but I want a "master" test  
runner that would require MyTester, MyOtherTester, MyFinalTester,  
etc. In this case, initialize\_things doesn't get called.

How can I replicate this startup() functionality that I need? I do  
NOT want to use setup(), as it slows things down considerably.

> **···**
>
> On Mar 25, 4:29 pm, "Luke St.Clair" \<secureb...@gmail.com\> wrote:
> 
> > On Mar 24, 12:39 pm, "Luke St.Clair" \<secureb...@gmail.com\> wrote:
> > 
> > \> I think this is what I'm going to go with - I'll have a test case for  
> > \> each possible param value (there are about 10), and each one will set  
> > \> a few additional global variables. Then, each test case will include  
> > \> the same module, which will call functions with params set by the  
> > \> global variables.
> > 
> > The biggest issue I'm running into right now is not having startup(),  
> > or code that runs once per test suite, not once per test case.
> > 
> > Is this in test::unit yet?

---

<div class="post-metadata">

**Author:** ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)\
**Post date:** [25 March 2009 23:41 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/11 "2009-03-25T23:41:45Z")

</div>

Luke St.Clair wrote:

> The biggest issue I'm running into right now is not having startup(),  
> or code that runs once per test suite, not once per test case.
> 
> Is this in test::unit yet?

There are code samples and I think plugins which add that.

How about in the base module...

&nbsp;&nbsp;&nbsp;def setup  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@done ||= suite\_setup()  
&nbsp;&nbsp;&nbsp;end

Then put what you want in the suite\_setup ?

---

<div class="post-metadata">

**Author:** ![Kouhei\_Sutou1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/kouhei_sutou1/32/2034_2.png) [@Kouhei\_Sutou1](https://rubytalk.org/u/Kouhei_Sutou1)\
**Post date:** [26 March 2009 12:31 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/12 "2009-03-26T12:31:45Z")

</div>

Hi,

In \<55f56345-3524-40d0-8a9a-85bef4448ae7@d7g2000prl.googlegroups.com\>  
&nbsp;&nbsp;"Re: Test::Unit - same test, different "args"" on Thu, 26 Mar 2009 08:26:47 +0900,

> **···**
>
> "Luke St.Clair" \<secureboot@gmail.com\> wrote:
> 
> > On Mar 24, 12:39 pm, "Luke St.Clair" \<secureb...@gmail.com\> wrote:
> > 
> > > I think this is what I'm going to go with - I'll have a test case for  
> > > each possible param value (there are about 10), and each one will set  
> > > a few additional global variables. Then, each test case will include  
> > > the same module, which will call functions with params set by the  
> > > global variables.
> > 
> > The biggest issue I'm running into right now is not having startup(),  
> > or code that runs once per test suite, not once per test case.
> > 
> > Is this in test::unit yet?
> 
> Type 'sudo gem install test-unit'. Test::Unit 2.x supports  
> it:  
> &nbsp;&nbsp;[http://test-unit.rubyforge.org/test-unit/classes/Test/Unit/TestCase.html](http://test-unit.rubyforge.org/test-unit/classes/Test/Unit/TestCase.html)
> 
> Thanks,  
> --  
> kou

---

<div class="post-metadata">

**Author:** ![Luke\_St.Clair](https://avatars.discourse-cdn.com/v4/letter/l/779978/32.png) [@Luke\_St.Clair](https://rubytalk.org/u/Luke_St.Clair)\
**Post date:** [26 March 2009 00:01 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/13 "2009-03-26T00:01:48Z")

</div>

Yes, that's clearly the best way for me to do this outside of startup  
() - don't know what I was thinking there.

> **···**
>
> On Mar 25, 4:39 pm, Phlip \<phlip2...@gmail.com\> wrote:
> 
> > Luke St.Clair wrote:  
> > \> The biggest issue I'm running into right now is not having startup(),  
> > \> or code that runs once per test suite, not once per test case.
> > 
> > \> Is this in test::unit yet?
> > 
> > There are code samples and I think plugins which add that.
> > 
> > How about in the base module...
> > 
> > def setup  
> > @@done ||= suite\_setup()  
> > end
> > 
> > Then put what you want in the suite\_setup ?

---

<div class="post-metadata">

**Author:** ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)\
**Post date:** [26 March 2009 01:01 UTC](https://rubytalk.org/t/test-unit-same-test-different-args/52461/14 "2009-03-26T01:01:48Z")

</div>

Luke St.Clair wrote:

> > How about in the base module...
> > 
> > &nbsp;&nbsp;&nbsp;def setup  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@@done ||= suite\_setup()  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > Then put what you want in the suite\_setup ?
> 
> Yes, that's clearly the best way for me to do this outside of startup  
> () - don't know what I was thinking there.

I was thinking I don't know if that runs once per suite or once per test run...
