Jul 8, 2013

Unit Testing in Perl

We can write test scripts in Perl using Test::Simple and Test::More in easy way.

Test::More is an yet another framework for writing test scripts

Lets explain Test::More module with examples.

ok() vs is() 

1) Similar to ok(), is() and isnt() compare their two arguments with eq and ne respectively and use the result of that to determine if the test succeeded or failed. 

is($hsh{a}, 200, 'Test 200');
isnt($hsh{a}, 200, 'Test 200');

are similar to these:

ok($hsh{a} eq 200, 'Test 200');
ok($hsh{a} ne 200, 'Test 200');

2) They produce better diagnostics on failure. 
ok() cannot know what you are testing for (beyond the name)
but 
is() and isnt() know what the test was and why it failed. 

In case of test fail, ok() shows fail like below :
ok($hsh{a} == 200, 'Test 200');
# not ok 5 - Fail
#   Failed test 'Fail'
#   at main.pl line 21.

In case of test fail, is() or isnt() shows fail like below :
is($hsh{a}, 200, 'Test 200');
# not ok 5 - Fail
#   Failed test 'Fail'
#   at main.pl line 20.
#          got: '100'
#     expected: '200'

like()
like() allows to use regular exporessions in writing test cases
The following example, we are trying to check $str contains string 'freedom' or not

like($str, qr/freedom/i, 'String contains Freedom - ignore case');
ok($str =~ /freedom/i, 'String contains Freedom - ignore case');


cmp_ok()
cmp_ok() also useful in those cases where you are giving explicit conditions like >=, <=, ==, != etc.,

cmp_ok($scalar, "<=", 200, '10 is less than or equal to 200 - pass');
cmp_ok($scalar, "==", 10, '10 is equal to 10 - pass');

can_ok()

Syntax:
can_ok($module, @methods);
can_ok($object, @methods);

can_ok checks if a mthod exists in an object, here $obj is the object of "support" class
can_ok also checks if a method exists in an class, here "support" is the class
can_ok is good at taking mutiples methods to test at one shot

E.g.,
can_ok($obj, "add");
can_ok("support", "multiply");
can_ok("support", qw(test add multiply));

Lets explain the above methods with an example :
In the following example, we use support.pm for testing object, class and methods

support.pm
#!/usr/bin/perl

package support;

use strict;
use warnings;
use Data::Dumper;

sub new {
    my($class) = shift;
        
    my($self) = {};

    return(bless($self, $class));
}


sub multiply {
  my $a = shift;
  my $b = shift;
 
  return ($a*$b);
}  

sub add {
  my $a = shift;
  my $b = shift;
 
  return ($a+$b);
}  

sub test {
    print "\n test mehthod inside support package"; 
}  

1;  

main.pl
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Test::More tests=>20;
use support;

my $obj = new support;

#You usually want to test if the module you're testing loads ok, rather than just vomiting if its load fails. It's recommended that you run use_ok() inside a BEGIN block so its functions are exported at compile-time and prototypes are properly honored.
BEGIN { use_ok("CGI"); }

#print "\n Obj : " . Dumper($obj);


#Testing Packages and Objects -----------------------------------------------
#Testing an object belongs to a class or not
ok (defined($obj) && ref $obj eq 'support', 'support obj new worked');

#can_ok checks if a mthod exists in an object, here $obj is the object of "support" class
#can_ok also checks if a method exists in an class, here "support" is the class
#can_ok is good at taking mutiples methods to test at one shot
can_ok($obj, "add");
can_ok("support", "multiply");
can_ok("support", qw(test add multiply));


#isa_ok checks if an object belongs to a class or not
isa_ok($obj, 'support');


#Testing Values -----------------------------------------------
my $scalar = 10;
my %hsh    = (a=>100, b=>200, c=>300);
my $str    = 'Freedom lies in being bold';


#is() vs ok()
#is() is recommended over ok()
#ok() function doesn't provide good diagnostic output.
#ok() cannot know what you are testing for (beyond the name), but is() and isnt() know what the test was and why it failed.

ok($scalar == 10, 'Pass');
is($scalar, 10, 'Pass');

is($hsh{a}, 100, 'Pass');
ok($hsh{a} == 100, 'Pass');

#is($hsh{a}, 200, 'Fail');
# not ok 5 - Fail
#   Failed test 'Fail'
#   at main.pl line 20.
#          got: '100'
#     expected: '200'

#ok($hsh{a} == 200, 'Fail');
# not ok 5 - Fail
#   Failed test 'Fail'
#   at main.pl line 21.

isnt($scalar, 20, 'Pass');

#like() allows to use regular exporessions in writing test cases
like($str, qr/freedom/i, 'String contains Freedom - ignore case');
ok($str =~ /freedom/i, 'String contains Freedom - ignore case');

#It's also useful in those cases where you are comparing numbers and applying conditions
cmp_ok($scalar, "<=", 200, '10 is less than or equal to 200 - pass');
cmp_ok($scalar, "==", 10, '10 is equal to 10 - pass');


Output:

1..20
ok 1 - use CGI;
ok 2 - support obj new worked
ok 3 - support->can('add')
ok 4 - support->can('multiply')
ok 5 - support->can(...)
ok 6 - The object isa support
ok 7 - Pass
ok 8 - Pass
ok 9 - Pass
ok 10 - Pass
ok 11 - Pass
ok 12 - String contains Freedom - ignore case
ok 13 - String contains Freedom - ignore case
ok 14 - 10 is less than or equal to 200 - pass
ok 15 - 10 is equal to 10 - pass
# Looks like you planned 20 tests but ran 15.
  


No comments:

Post a Comment