Inheriting Tests

     

Your boss thinks highly of your new, shiny Queue module. "Great," she says, "but we need a subclass that will enqueue only single, unhyphenated words." Before you became a confident tester, this might have worried you. It's not scary anymore, though. [*] Thanks to Test::Class , there's not much more to do.

[*] Of course, you might worry if she could see the paper clip trebuchet you've been using to fire paper clips at coworkers.

This lab explains how to write tests for subclasses when you already have Test::Class tests for their parents.

How do I do that?

A subclass inherits from a parent class, so why not have tests inherit from a parent test? Except for the enqueue( ) method, the features of the two classes are the same. Because the tests for Queue enqueue only words, you can reuse the test methods declared in Queue::Test .

Create the directory Queue/Word/ , and save the following as Queue/Word/Test.pm :

 package Queue::Word::Test;          use base 'Queue::Test';          use Queue::Word;     use Test::More;     use Test::Exception;          sub setup_queues : Test( setup => 2 )     {         my ($self) = @_;              $self->{empty}    = Queue::Word->new(  );         $self->{twoitems} = Queue::Word->new(qw( howdy bonjour ));              isa_ok( $self->{$_}, 'Queue::Word' ) for qw( empty twoitems );     }          sub check_only_words : Test(5)     {         my ($self) = @_;              lives_ok { $self->{empty}->enqueue('wassup') } "can enqueue words";         lives_ok { $self->{empty}->enqueue('HeLlO') } "case doesn't matter";         dies_ok  { $self->{empty}->enqueue(1981) } "can't enqueue integers";         dies_ok  { $self->{empty}->enqueue(10.9) } "can't enqueue decimal";         dies_ok  { $self->{empty}->enqueue('Transzorp Diode') }             "can't enqueue names of cyborgs";     }          1; 

Next, create the Queue::Word module that extends Queue . Save the following code as Queue/Word.pm :

 package Queue::Word;          use strict;     use warnings;          use base 'Queue';          sub enqueue     {         my ( $self, $item ) = @_;              die "can only enqueue words, not '$item'"             unless $item =~ m/ ^ [A-Z]+ $ /ix;              push @$self, $item;     }          1; 

Now create a test file, queue_word.t , so that it runs the tests for both classes. Save the following code as queue_word.t :

 #!perl          use Queue::Test;     use Queue::Word::Test;          Test::Class->runtests(  ); 

Run it with prove :

 $  prove queue_word.t  queue_word....ok     All tests successful.     Files=1, Tests=31,  1 wallclock secs ( 0.07 cusr +  0.00 csys =  0.07 CPU) 

What just happened ?

Because Queue::Word::Test is a subclass of Queue::Test , it inherits all the test methods from Queue::Test . It must override setup_queues( ) so that the fixture creates objects of the proper class, though.

There's no practical benefit in rewriting the tests for size ( ) and dequeue( ) , as the subclass does not change their behavior. The enqueue( ) method, however, is more restrictive with its arguments. check_only_words( ) tests that the program dies when it receives invalid arguments.

Calling runtests( ) tells Test::Class to run all tests in both loaded test classes. Because the test subclass adds additional testing methods, the queue_word.t test file runs more tests than did the queue.t test file.



Perl Testing. A Developer's Notebook
Perl Testing: A Developers Notebook
ISBN: 0596100922
EAN: 2147483647
Year: 2003
Pages: 107

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net