Warning: strpos() [function.strpos]: needle is not a string or an integer in /home/lancew/public_html/blog/index.php on line 61
JudoGeek Blog - TDD with Perl, Episode 2 - Getting Started. Lance Wicks
Lance Wicks
Kiwi,
Judoka,
Geek,
Husband
Daddy!

JudoGeek Blog

TDD with Perl, Episode 2 - Getting Started. 

Test Driven Development or TDD is a increasingly common phrase and idea that you need to get your head around. The concept here is that you write pieces of software that tests the actual software you are writing.

The idea is that for every subroutine you write, you write a test (or several tests actually) that proves it works. In the purest methodology you write the test first, then the code. But for someone new to it, this is not realistic. That said, the sooner you start writing tests, the more sense it makes and the easier the process.

So how do you begin? Well that is what we cover here, Basically what we will do is create a "Smoke Test" script and a bunch of generic tests and also start of testing some of your subroutines. What I include here is based heavily on .......

What is a smoke test?
Okay, here is my take on what smoke testing is. A smoke test is basically a script that runs a bunch of other tests. The idea being that it'll test all your other tests and come back saying all is well. Your smoke test will be run all the time just to give you confidence that everything is well with your project. Think of it as a summary of all your other tests.

How do I start smoke testing?
Basically you need a smoketest script (mine is called smoke_test.pl) and some .t test scripts. So lets start with the smoketest script, heres mine as an example:

#!/usr/bin/perl
use File::Find::Rule;
use Test::Harness qw(&runtests);

my $rule = File::Find::Rule->new;
$rule->or(
$rule->new->directory->name('CVS')->prune->discard,
$rule->new->file->name( '*.t' )
);
my @start = @ARGV ? @ARGV : '.';
my @files;
for ( @start ) {
push( @files, (-d) ? $rule->in($_) : $_ );
}

runtests(@files);


You "should" be able to cut and paste this into a file and save it as smoke_test.pl. Next you need a test script, here is one I have:

#!/usr/bin/perl
use File::Find::Rule;
use Test::More qw(no_plan);

sub check {
my $filename = shift;
local $/ = undef;
open( my $fh, $filename ) or
return fail( "Couldn't open $filename: $!" );
my $text = <$fh>;
close $fh;
like( $text, qr/use strict;/,
"$filename uses strict" );
} # check()


my $rule = File::Find::Rule->new;
$rule->file;
$rule->name( '*.pm', '*.pl' );


my @files = $rule->in( './');
for (@files){
check($_);
}


You can cut and paste this into a file called say use_strict.t and save it.

Run you smoke_test.pl script (perl smoke_test.pl) and it should run the use_strict.t test on every .pm file in that and sub directories. Now, if the only code you have in this directory, your smoke test will fail... that's ok, its what should happen at this point.

If you look at the output of the smoke test you should be able to see that smoke_test.pl failed the use_strict test, which is right as at the moment it does not have "use strict;" near the top. Go add it just above use "File::Find::Rule;" and re-run the smoke test. Hopefully it will now pass.

Congratulations!
You have now done your first bit of test driven development TDD. Your use_strict test pointed out a flaw in your code (you didn't have "use strict;" in your smoke test). You corrected the error and now you test passes.

So whats next?
Best practise says we should use "Use warnings;" in our code too, so lets test that we are doing that. Here is my example use_warnings.t file, feel free to cut and paste:

#!/usr/bin/perl
use File::Find::Rule;
use Test::More qw(no_plan);

sub check {
my $filename = shift;
local $/ = undef;
open( my $fh, $filename ) or
return fail( "Couldn't open $filename: $!" );
my $text = <$fh>;
close $fh;
like( $text, qr/use warnings;|perl -w/,
"$filename uses warnings" );
} # check()


my $rule = File::Find::Rule->new;
$rule->file;
$rule->name( '*.pm', '*.pl' );


my @files = $rule->in( './');
for (@files){
check($_);
}


Now run your smoketest script again. Oh no! It fails again right? Similar issue, your smoke_test.pl script hasn't goy "use warnings;" in there has it, go ahead and add it. Hopefully your smoketest should pass now.

You are now a TDD developer!!!
You wrote your test first, it failed, you altered your code, the test passed.
This is basically what TDD is all about, you decide on something you want to write/add, before you add it, you write a test to prove the feature worked. You run your test, which fails. You THEN write the code to do whatever you wanted, then test again, hopefully it passes. Then you repeat this for every change to your project. Write test, run test, write code, run test....

But I have not tested my code?
True, so lets do an example of that now...
We are going to write a little module that tests if testing is cool.
Start of by creating a file called tdd_is_cool.pm and a file called tdd_is_cool.t
Inside tdd_is_cool.t lets write some stuff to let us get started testing using Perl's Test::More (which we have already been using):

#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 2;


So hopefully you get the first three lines already, they are basically just normal for Perl code ok. Now, line three... Line three loads the Test::More module and tells it that we are going to run two tests.
Next we add:

use_ok( 'tdd_is_cool' );

This tests that you can load your tdd_is_cool.pm file ok. You can run your smoketest now and it will fail.

now add this line:

is( tdd_is_cool::test_cool(),'1','TDD is cool!');

This line calls a subroutine in our (unwritten) module and checks if it returns '1', if so then testing is cool. You can again run your test (and your smoketest and they will both fail).

So lets write our module, heres a bare minimum for you to cut and paste into tdd_is_cool.pm:

#!/usr/bin/perl
use strict;
use warnings;
package tdd_is_cool;


sub test_cool {
return('1');
}
1;



Now run your tests and hopefully they should pass!! You are now well down the path of TDD.

Remember, its as simple as deciding what you want to write, writing a test for what you are going to write, then writing the code that does it.
[ view entry ] ( 992 views ) permalink

<<First <Back | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Next> Last>>