geekgrrl has asked for the wisdom of the Perl Monks concerning the following question:
I'm in the middle of trying to get my test suite to run successfully for the last day and a half. So i am feeling philosophical about testing, and am wondering what others do to test their code?
I use Test::Simple, and just have a whole bunch of tests that use WWW::Mechanize to hammer away at my website trying out different features. I also have simpler tests that just test subroutines or objects.
I'm wondering what your favorite test modules are, and how you go about testing (or if you don't). Does anyone actually write the tests before you do the coding? What is your method? Whenever I add a new feature, I try and get myself to write a script to test it.
I've found having tests does save me a lot of debugging time, because I'm basically debugging the code in advance. And there is some satisfaction in seeing all of those ok's fly by.
Re: testing code
by Steve_p (Priest) on May 05, 2004 at 22:44 UTC
|
For testing modules, Test::More is the main module that I use. Test::Exception is probably my second most used because I got bored of writing eval blocks to catch die.
Generally, I try to write as many of my tests as possible before coding. That way I know how the API of my modules will work, and I can catch an ugly API before I would be able to otherwise. Then, I write code for the modules and make sure I get all my tests to pass without warnings. After that, I run Devel::Cover over it all to make sure I've got good test coverage, and add test cases as needed.
| [reply] [d/l] [select] |
|
ooh.. cool new modules to try. thanks!
I definitely want to try out Test::Exception - I'm often using eval blocks. And Devel::Cover looks quite interesting. I haven't thought about using coverage reports before.
One of these days I know I should graduate up to Test::More, but i've been holding off so far...it's that laziness factor, i guess, and Test::Simple is just so...simple and easy.
Update: I've switched my eval blocks over to use Test::Exception routines like throws_ok and lives_ok. It makes the code much more readable, and saves me some typing, too.
| [reply] |
|
We use Test::More all the time.
Every <module>.t we write has a corresponding t/<module>.t test file written for it.
I've included a real Makefile.PL from one of our projects, and a sample Test::More template .t file.
You should also read the ExtUtils::MakeMaker doco for more sophisticated ways of calling make test
# Makefile.PL
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'txu_bims',
VERSION_FROM => 'VERSION.pm',
test => {TESTS => './TXU/BIMS/t/*.t ./TXU/t/*.t'
+}, # how to pass multiple test paths
PMLIBDIRS => ['./TXU/BIMS', './TXU'],
PREREQ_PM => {
Log::Log4perl => 0.36,
},
);
# template Module/Under/t/Test.t
#!/usr/bin/perl -w
use strict;
use Test::More qw(no_plan);
use Module::Under::Test;
# test go here
my $obj = Module::Under::Test->new();
isa_ok($obj, 'Module::Under::Test');
is($obj->method(), 'expected output', 'standard test');
is_deeply($obj->meth_retn_ref(), {complex => {structure => ['here']}},
+ 'method returns ref to complex structure');
After this, its as simple as ...
perl Makefile.PL
make test
More complex examples of calling make test are ...
-
make test TEST_VERBOSE=1
for more detailed information on test execution
-
make testdb TEST_FILE=path/to/script.t TESTDB_SW=-d:ptkdb
to run just path/to/script.t under the GUI debugger ptkdb (which is a great debugger
*UPDATE* - proxy dropped out half way through uploading this - added the point list
+++++++++++++++++
#!/usr/bin/perl
use warnings;use strict;use brain;
| [reply] [d/l] [select] |
|
| [reply] |
|
ok ( $foo =~ /bar/, 'contains bar');
ok ( UNIVERSAL::isa($o, 'MyClass'), 'isa MyClass' );
ok( $foo eq 'bar', 'equals bar' );
you can say
like( $foo, qr/foo/, 'contains bar' );
isa_ok( $o, 'MyClass' );
is( $foo, 'bar', 'equals bar' );
which is marginally easier to comprehend. You also get more informative test failures, for example if you do:
is( 'apples', 'oranges', 'expecting to find some oranges' );
you'll get the informative
not ok 1 - expecting to find some oranges
# Failed test (-e at line 1)
# got: 'apples'
# expected: 'oranges'
rather than just
not ok 1 - expecting to find some oranges
You'll find the same sort of advantages with other Test:: modules. You get to express you test more precisely and you get better feedback on test failures. | [reply] [d/l] [select] |
Re: testing code
by nmcfarl (Pilgrim) on May 05, 2004 at 23:20 UTC
|
At one job I was good. Tests on a cron job, tests for each and every object, tests in the distribution system. It mattered.
These days even though it's a job, it's non-critical. Oddly enough it must go out, but if it's a little off that's ok I can fix it. So I use Test::Simple for my single test script, that covers very little functionality, just the tricky stuff.
The theory was that it'd be faster. And it has been, but that's starting to end. The code is getting large enough that changes are having ripple effects. That tests are justified, and are starting to get written. I'm thinking about test first, but that seems like such a hurdle. It's just too much work, I wonder what level of quality would be required for me to take that leap.
| [reply] |
|
| [reply] |
|
I agree with the sentiment, if applied to testing in general, but I don't see how it furthers the argument for testing first. Perhaps I'm missing something.
As an Aside:
If you're wondering the reason why testing is not a big priority at this job, it's because the perl is almost all demos and one offs. If it's not worth saving, it's not worth testing (much) in my mind. So mainly I seem to be testing the code that gets re-used. As that code grows, so do the tests.
| [reply] |
|
|
Amen! Whenever I feel lazy, or want to procrastinate writing a test, I just remind myself of how lame it is to spend hours debugging the code later on, often with people breathing down my back.
| [reply] |
Re: testing code
by adrianh (Chancellor) on May 06, 2004 at 16:38 UTC
|
| [reply] |
Re: testing code
by nmcfarl (Pilgrim) on May 08, 2004 at 20:25 UTC
|
So it happens that there is a new perl.com article on this very topic, just out on friday (May 07, 2004) . It's good, and it offers module suggestions. I recommend you read it. | [reply] |
Re: testing code
by geekgrrl (Pilgrim) on May 12, 2004 at 19:53 UTC
|
Thanks to everyone for their great advice.
I thought I would mention that I'm currently trying some new modules:
Test::More and Test::Exception.
I have yet to fully figure out how to run Devel::Cover for my code.
Right now, to run my tests I run the command
perl t/runtests.pl <server_name>
That script calls all of my various test scripts. Kind of like Test::Harness, which I should probably switch over to (except I didn't see, at first glance, how to pass in that server name argument.) For some reason, everytime I have run it with Devel Cover, I just get an analysis of the script runtests.pl, not the code that is tested. Any advice would be welcome.
I also discovered this node Autogenerate Test Scripts via post 352687. It is a script that will autogenerate stub test scripts for you. It's great - I'm using it in conjunction with Test::More right now. Oh baby! | [reply] [d/l] |
|
That script calls all of my various test scripts. Kind of like Test::Harness, which I should probably switch over to
You will also probably find the command line prove utility useful (which you'll find in the newer versions of Test::Harness).
(except I didn't see, at first glance, how to pass in that server name argument.)
You could always just use an environment variable. Personally I use the notes facility in Module::Build to store any test configuration information.
For some reason, everytime I have run it with Devel Cover, I just get an analysis of the script runtests.pl, not the code that is tested. Any advice would be welcome.
Is the directory containing your test scripts in @INC (which is ignored by default)? Check out the command line options for ways to get around this.
| [reply] [d/l] [select] |
|
|