Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

heusserm (4461)

heusserm
  (email not shown publicly)
http://www.xndev.com/
AOL IM: MatthewHeusser (Add Buddy, Send Message)

Matt Heusser is JAPH and an XP-Er [xprogramming.com]. (The Methodology, not the Operating System.) Right now, he's doing a lot of Test Driven Development in Perl.

Journal of heusserm (4461)

Tuesday August 05, 2003
09:29 AM

Test-First of OO Modules

[ #13920 ]

I recently did a ten-minute talk on Test-First of OO modules. This got me to thinking 'hey, I should put this on my blog' ... which got me to thinking 'hey, I should have a blog. If it were RSS enabled, Steve Hoek could use it to test his RSS Reader ...' :-)

So, here it is:

Let's say we're going to create a module called 'SomeObject'.

We knoew SomeObject will be a container, and it will take three optional paramaters on creation: The values of the entries at A, B, and C.

SomeObject will have two methods, 'Get' and 'Set'

So, we design the following tests:

1) Does SomeObject.pm compile?
2) Does SomeObject have new and get methods?
3) If I new, does it create a SomeObject object?
4,5,6) With the Object I created above, does it have the correct values for A, B, C?
7) Is the entry for D "Undefined?"

The tests are below:

#---------BEGIN CODE---------#
#use lib wherever SomeObject is. ('./')?
use Test::More;
BEGIN { plan tests => 7 };
use_ok('SomeObject');

can_ok('SomeObject', qw(new get) );

my $t = SomeObject->new(1,2,3);
isa_ok($t, 'SomeObject');

my $a = $t->get('A');
ok($a, 1, "Get 1st Parameter");

my $b = $t->get('B');
ok($b, 2, "Get 2nd Parameter");

my $c = $t->get('C');
ok($c, 3, "Get 3rd Parameter");

my $d = $t->get('D');
my $blnOk = 0;
if (!defined($d)) { $blnOk=1;}
ok($blnOk==1, "Making sure no extra variables are created");
# --- If we really wanted to be slick, I'd
# iterate from D to ZZZ or so, but I don't
# The for would have a bln we'd check, so we'd
# only have one variable, not 26*26*26.
#
#---------END CODE---------#

When you run the test file intially, only the use should pass, because you haven't even _coded_ the other methods.

Then, you code and test. Eventually, the test results look like this:

1..7
ok 1 - use PH::SomeObject;
ok 2 - PH::SomeObject->can(...)
ok 3 - The object isa PH::SomeObject
ok 4 - Get 1st Parameter
ok 5 - Get 2nd Parameter
ok 6 - Get 3rd Parameter
ok 7 - Making sure no extra variables are created

Pretty nifty eh?

Not really, but it's a good start.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • my $d = $t->get('D');
    my $blnOk = 0;
    if (!defined($d)) { $blnOk=1;}
    ok($blnOk==1, "Making sure no extra variables are created");
    That might be better written as:
    my $d = $t->get('D');
    ok(!defined($d), "Making sure no extra variables are created");
    --

    --
    "Cake or Death!" .... "Cake please"
    • It'd be written even better as:
      my $d = $t->get('D');
      is( $d, 'expected_value', "get(D)");

      Use of is(), like() and isa_ok() is a very good thing where possible.

      -Dom

  • I'm *extremely* new to testing and this post was very informative for me. Thanks.

    But...

    What is test # 7 about?

    What if 'E' exists?

    What if the object is inherited, couldn't it have a 'D'? (hmm... that wouldn't happen during testing tho... right?)

    From a philosophical view, it would seem to me that tests should cover the requirements... and I didn't see anything in the requirement to drive test 7.

    It also seems that if you wanted to check that there were not extra variables created, you would need to enume
  • ok($a==1, "Testing 1st Parameter");

    is better written as

    is( $a, 1, "Testing 1st Parameter");

    for better diagnostics on failure. Any time you're writing

    ok( $a == 1 )

    you probably want

    is( $a, 1 );

    unless your name is Nick Clark, in which case you reall, really meant '==' so its cmp_ok($a, '==', 1 ) or Damian Conway, in which case there's probably a really good reason you used ok() instead of is().

    Even better would be:

    is( $a, 1, 'getting A' );

    Mentioning that you're "testing" something in a test