SlideShare ist ein Scribd-Unternehmen logo
1 von 49
Downloaden Sie, um offline zu lesen
josh mcadams
doubleclick/performics
stonehenge.com
introduction




what is testing?
introduction


Testing seems like a very simple concept.

Testing is the process of doing something, collecting the results of
what you just did, and then verifying that the results are what you
expected.

Even simpler, software testing can be reduced to saying that given a
known input, an expected output is produced.

Even with a simple definition, testing is a very complex subject that
is continually argued about.
introduction


Unit tests are tests, so they take the result of some action and
validate that result against what was expected.

Unit tests check small components of your system to make sure
that they are functioning correctly.

An automated test is a test that doesn’t necessarily require any
human intervention in order to run.

In Perl, you get a nice automated unit testing system for free with
prove, Test::Harness, Test::More, ExtUtils::MakeMaker,
Module::Build, and friends.
example problem




Throughout the talk, we’ll be creating a Perl module that will
calculate percentage of ownership for an owner in a condo.

The percentages are used for important things like association
elections and assessments, so they have to be correct or lawyers
will get involved.
example problem



The formula works by determining the percentage of the building
that an individual owns in proportion to the total livable space.
Common areas are not included.

The trick is that the actual square footage of any unit is weighted
using multiplier. Each floor up adds an extra hundredth to the
weight. For instance, a 600 square foot unit on the 11th floor would
be weighted at 600 * 1.11 = 666.
example problem



Don’t worry about units that span multiple floors.

Ninety-nine floors are the most that any building can have.

Don’t worry about matching up owners who have multiple units.

Underground floors all get a weight of zero, no matter how many
levels down they actually are.
working example




1   use warnings;
2   use strict;
3   use Test::More tests => 1;
4
5   BEGIN { use_ok('PercentOwnership'); }
working example


--(0)> prove t/percent_ownership.t
t/percent_ownership....
#   Failed test 'use PercentOwnership;'
#   at t/percent_ownership.t line 5.
#     Tried to use 'PercentOwnership'.
#     Error: Can't locate PercentOwnership.pm in @INC (@INC contains: ...) at (eval 3)
line 2.
# BEGIN failed--compilation aborted at t/percent_ownership.t line 5.
# Looks like you failed 1 test of 1.
t/percent_ownership....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 1
        Failed 1/1 tests, 0.00% okay
Failed Test           Stat Wstat Total Fail Failed List of Failed
-------------------------------------------------------------------------------
t/percent_ownership.t    1   256     1    1 100.00% 1
Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
working example




1   package PercentOwnership;
2
3   use warnings;
4   use strict;
5
6   1;
working example




--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....ok
All tests successful.
Files=1, Tests=1, 0 wallclock secs ( 0.04 cusr +   0.02 csys =   0.06 CPU)
working example



1   use warnings;
2   use strict;
3   use Test::More tests => 2;
4
5   BEGIN { use_ok('PercentOwnership') }
6
7   can_ok( 'PercentOwnership', 'new' );
working example



--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....
#   Failed test 'PercentOwnership->can('new')'
#   at t/percent_ownership.t line 7.
#     PercentOwnership->can('new') failed
# Looks like you failed 1 test of 2.
t/percent_ownership....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 2
        Failed 1/2 tests, 50.00% okay
Failed Test           Stat Wstat Total Fail Failed List of Failed
--------------------------------------------------------------------------
t/percent_ownership.t    1   256      2   1 50.00% 2
Failed 1/1 test scripts, 0.00% okay. 1/2 subtests failed, 50.00% okay.
working example


1   package PercentOwnership;
2
3   use warnings;
4   use strict;
5
6   sub new {}
7
8   1;
working example




--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....ok
All tests successful.
Files=1, Tests=2, 0 wallclock secs ( 0.04 cusr +   0.02 csys =   0.06 CPU)
working example



3   use Test::More tests => 3;
4
5   BEGIN { use_ok('PercentOwnership') }
6
7   can_ok( 'PercentOwnership', 'new' );
8   my $po = PercentOwnership->new();
9   isa_ok( $po, 'PercentOwnership' );
working example


--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....
#   Failed test 'The object isa PercentOwnership'
#   at t/percent_ownership.t line 9.
#     The object isn't defined
# Looks like you failed 1 test of 3.
t/percent_ownership....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 3
        Failed 1/3 tests, 66.67% okay
Failed Test           Stat Wstat Total Fail Failed List of Failed
-----------------------------------------------------------------------
t/percent_ownership.t    1   256     3    1 33.33% 3
Failed 1/1 test scripts, 0.00% okay. 1/3 subtests failed, 66.67% okay.
working example

1 package PercentOwnership;
2
3 use warnings;
4 use strict;
5
6 sub new {
7     my ($class) = @_;
8     my $self = bless {}, $class;
9     return $self;
10 }
11
12 1;
working example




--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....ok
All tests successful.
Files=1, Tests=3, 0 wallclock secs ( 0.04 cusr +   0.02 csys =   0.06 CPU)
working example


3 use Test::More tests => 4;
4
5 BEGIN { use_ok('PercentOwnership') };
6
7 can_ok( 'PercentOwnership', 'new' );
8 my $po = PercentOwnership->new();
9 isa_ok($po, 'PercentOwnership');
10
11 can_ok( $po, 'add_unit' );
working example



6 sub new {
7     my ($class) = @_;
8     my $self = bless {}, $class;
9     return $self;
10 }
11
12 sub add_unit {}
working example




11 can_ok( $po, qw(add_unit percent_ownership) );
12
13 $po->add_unit(
14     unit_number    => 101,
15     square_footage => 450,
16     floor          => 1,
17 );
working example


6 sub new {
7     my ($class) = @_;
8     my $self = bless {}, $class;
9     return $self;
10 }
11
12 sub add_unit {}
13
14 sub percent_ownership {}
working example



11   can_ok( $po, qw(add_unit percent_ownership) );
12
13   $po->add_unit(
14       unit_number    => 101,
15       square_footage => 450,
16       floor          => 1,
17   );
18
19   is( $po->percent_ownership( unit_number => 101 )
          , 100, 'single unit condo' );
working example


--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....
#   Failed test 'single unit condo'
#   at t/percent_ownership.t line 19.
#           got: undef
#     expected: '100'
# Looks like you planned 4 tests but ran 1 extra.
# Looks like you failed 1 test of 5 run.
t/percent_ownership....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 5
        Failed 1/4 tests, 75.00% okay
Failed Test            Stat Wstat Total Fail Failed List of Failed
-----------------------------------------------------------------------
t/percent_ownership.t     1   256     4    2 50.00% 5
Failed 1/1 test scripts, 0.00% okay. 0/4 subtests failed, 100.00% okay.
working example
1 package PercentOwnership;
2
3 use warnings;
4 use strict;
5
6 sub new {
7     my ($class) = @_;
8     my $self = bless {}, $class;
9     return $self;
10 }
11
12 sub add_unit { }
13
14 sub percent_ownership { return 100; }
15
16 1;
working example




--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....ok
All tests successful.
Files=1, Tests=5, 0 wallclock secs ( 0.04 cusr +   0.02 csys =   0.06 CPU)
working example

9 SINGLE_UNIT: {
10     my $po = PercentOwnership->new();
11     isa_ok( $po, 'PercentOwnership' );
12
13     can_ok( $po, qw(add_unit percent_ownership) );
14
15     $po->add_unit(
16         unit_number    => 101,
17         square_footage => 450,
18         floor          => 1,
19     );
20
21     is( $po->percent_ownership(
            unit_number => 101 ), 100,
22         'single unit condo' );
23 }
working example
25 TWO_UNITS: {
26     my $po = PercentOwnership->new();
27     isa_ok( $po, 'PercentOwnership' );
28
29     can_ok( $po, qw(add_unit percent_ownership) );
30
31     $po->add_unit(
32         unit_number    => 101,
33         square_footage => 450,
34         floor          => 1,
35     );
36
37     $po->add_unit(
38         unit_number    => 102,
39         square_footage => 450,
40         floor          => 1,
41     );
42
43     is( $po->percent_ownership( unit_number => 101 ), 50,
44         'single unit condo' );
45 }
working example


--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....NOK 8
#   Failed test 'single unit condo'
#   at t/percent_ownership.t line 43.
#           got: '100'
#     expected: '50'
# Looks like you failed 1 test of 8.
t/percent_ownership....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 8
        Failed 1/8 tests, 87.50% okay
Failed Test            Stat Wstat Total Fail Failed List of Failed
-----------------------------------------------------------------------
t/percent_ownership.t     1   256     8    1 12.50% 8
Failed 1/1 test scripts, 0.00% okay. 1/8 subtests failed, 87.50% okay.
working example

5 use List::Util qw(sum);
...
13 sub add_unit {
14     my ( $self, %unit_info ) = @_;
15
16     $self->{unit_info}->{ $unit_info{unit_number} } = %unit_info;
17 }
18
19 sub percent_ownership {
20     my ( $self, %args ) = @_;
21
22     my $building_size = sum map {
        $self->{unit_info}->{$_}->{square_footage} }
23       keys %{ $self->{unit_info} };
24
25     my $unit_size =
26       $self->{unit_info}->{ $args{unit_number} }->{square_footage};
27
28     return sprintf( quot;%0.4fquot;, $unit_size / $building_size ) * 100;
29 }
working example




--(0)> prove -Ilib t/percent_ownership.t
t/percent_ownership....ok
All tests successful.
Files=1, Tests=8, 1 wallclock secs ( 0.06 cusr +   0.02 csys =   0.08 CPU)
tap


1..8
ok 1 - use PercentOwnership;
ok 2 - PercentOwnership->can('new')
ok 3 - The object isa PercentOwnership
ok 4 - PercentOwnership->can(...)
ok 5 - single unit condo
ok 6 - The object isa PercentOwnership
ok 7 # skip I'm lazy
not ok 8 - single unit condo # TODO I just havn't figured it out yet
#    Failed (TODO) test 'single unit condo'
#    at t/percent_ownership.t line 45.
#           got: '50'
#      expected: '51'
test::class
test::class
1 package TestPercentOwnership;
2
3 use warnings;
4 use strict;
5 use base qw(Test::Class);
6 use Test::More;
7
8 __PACKAGE__->runtests unless caller;
9
10 sub startup_test : Test( startup => 2 ) {
11     use_ok('PercentOwnership');
12     can_ok( 'PercentOwnership', 'new' );
13 }
14
15 1;
test::class

15 sub single_unit : Test(3) {
16     my ($self) = @_;
17     my $po = PercentOwnership->new();
18     isa_ok( $po, 'PercentOwnership' );
19     can_ok( 'PercentOwnership'
        , qw(add_unit percent_ownership) );
20
21     $po->add_unit(
22         unit_number    => 101,
23         square_footage => 450,
24         floor          => 1,
25     );
26
27     is( $po->percent_ownership( unit_number => 101 ), 100,
28         'single unit condo' );
29 }
test::differences



3 use Test::More qw(no_plan);
4
5 my $expected = 'This is a multiline
6 string of text
7 that is not the easiest thing to
8 display.';
9
10 my $got = $expected;
11 substr($got, 12, 1) = 'i';
12
13 is $got, $expected, 'The are who we thought they were';
test::differences

--(0)> prove scalar_is_deeply.t
is_deeply....
#   Failed test 'The are who we thought they were'
#   at is_deeply.t line 13.
#           got: 'This is a muitiline
# string of text
# that is not the easiest thing to
# display.'
#     expected: 'This is a multiline
# string of text
# that is not the easiest thing to
# display.'
# Looks like you failed 1 test of 1.
is_deeply....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 1
        Failed 1/1 tests, 0.00% okay
Failed Test Stat Wstat Total Fail Failed List of Failed
-------------------------------------------------------------------------------
is_deeply.t     1   256     1    1 100.00% 1
Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
test::differences

3 use Test::More qw(no_plan);
4 use Test::Differences;
5
6 my $expected = 'This is a multiline
7 string of text
8 that is not the easiest thing to
9 display.';
10
11 my $got = $expected;
12 substr($got, 12, 1) = 'i';
13
14 eq_or_diff $got, $expected,
    'They are who we thought they were';
test::differences

--(0)> prove scalar_test_differences.t
test_differences....NOK 1
#   Failed test 'They are who we thought they were'
#   at test_differences.t line 14.
# +---+----------------------------------+----------------------------------+
# | Ln|Got                                |Expected                         |
# +---+----------------------------------+----------------------------------+
# * 1|This is a muitiline                 |This is a multiline              *
# | 2|string of text                      |string of text                   |
# | 3|that is not the easiest thing to |that is not the easiest thing to |
# | 4|display.                            |display.                         |
# +---+----------------------------------+----------------------------------+
# Looks like you failed 1 test of 1.
test_differences....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 1
        Failed 1/1 tests, 0.00% okay
Failed Test         Stat Wstat Total Fail Failed List of Failed
-------------------------------------------------------------------------------
test_differences.t     1   256     1    1 100.00% 1
Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
test::differences



1   use warnings;
2   use strict;
3   use Test::More qw(no_plan);
4
5 my $expected = { name => 'Josh',
                    pets => [qw( ella ginger )] };
6 my $got = bless {%$expected}, 'Person';
7 $got->{name} = 'Heather';
8
9 is $got, $expected, 'Structures are different';
test::differences


--(0)> prove ref_is_deeply.t
ref_is_deeply....
#   Failed test 'Structures are different'
#   at ref_is_deeply.t line 9.
#           got: 'Person=HASH(0x183beb8)'
#     expected: 'HASH(0x183be40)'
# Looks like you failed 1 test of 1.
ref_is_deeply....dubious
        Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 1
        Failed 1/1 tests, 0.00% okay
Failed Test      Stat Wstat Total Fail Failed List of Failed
-----------------------------------------------------------------------
ref_is_deeply.t     1   256     1    1 100.00% 1
Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
test::differences


1   use   warnings;
2   use   strict;
3   use   Test::More qw(no_plan);
4   use   Test::Differences;
5
6 my $expected = { name => 'Josh',
                    pets => [qw( ella ginger )] };
7 my $got = bless {%$expected}, 'Person';
8 $got->{name} = 'Heather';
9
10 eq_or_diff $got, $expected,
        'Structures are different';
test::differences
--(0)> perl ref_test_differences.t
not ok 1 - Structures are different
#    Failed test 'Structures are different'
#    at ref_test_differences.t line 10.
# +----+----------------------+-------------------+
# | Elt|Got                    |Expected          |
# +----+----------------------+-------------------+
# *    0|bless( {              |{                 *
# *    1| name => 'Heather', | name => 'Josh', *
# |    2| pets => [            | pets => [        |
# |    3|    'ella',           |    'ella',       |
# |    4|    'ginger'          |    'ginger'      |
# |    5| ]                    | ]                |
# *    6|}, 'Person' )         |}                 *
# +----+----------------------+-------------------+
1..1
# Looks like you failed 1 test of 1.
test::deep


3   use Test::More qw(no_plan);
4   use Test::Deep;
5
6   my $obj = bless { name => 'x' }, 'Thing';
7
8 cmp_deeply( $obj,
9     all( isa('Thing')
    , noclass(
        subhashof( { name => 'x', rank => 'y' } )
    ) ) );
10 cmp_deeply( $obj,
    any( isa('Thing'), isa('OtherThing') ) );
test::mockobject


3 use Test::More qw(no_plan);
4 use Test::MockObject;
5
6 my $mock = Test::MockObject->new();
7 isa_ok( $mock, 'Test::MockObject' );
8
9 $mock->set_isa( 'DBI', 'DBIx::Class' );
10 isa_ok( $mock, 'DBIx::Class' );
11 isa_ok( $mock, 'DBI' );
thank you
yapc.org/America

Weitere ähnliche Inhalte

Was ist angesagt?

JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven Practises
Robert MacLean
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
varuntaliyan
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
nicobn
 
T sql denali code Day of .Net
T sql denali code Day of .NetT sql denali code Day of .Net
T sql denali code Day of .Net
KathiK58
 

Was ist angesagt? (20)

Fine-grained Processing of CVS Archives with APFEL
Fine-grained Processing of CVS Archives with APFELFine-grained Processing of CVS Archives with APFEL
Fine-grained Processing of CVS Archives with APFEL
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
 
Programming JVM Bytecode with Jitescript
Programming JVM Bytecode with JitescriptProgramming JVM Bytecode with Jitescript
Programming JVM Bytecode with Jitescript
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
 
Student management system
Student management systemStudent management system
Student management system
 
JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven Practises
 
Programming JVM Bytecode
Programming JVM BytecodeProgramming JVM Bytecode
Programming JVM Bytecode
 
Unit Testing using PHPUnit
Unit Testing using  PHPUnitUnit Testing using  PHPUnit
Unit Testing using PHPUnit
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Phpunit testing
Phpunit testingPhpunit testing
Phpunit testing
 
T sql denali code Day of .Net
T sql denali code Day of .NetT sql denali code Day of .Net
T sql denali code Day of .Net
 
Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8
 
Unit Testing in Angular(7/8/9) Using Jasmine and Karma Part-2
Unit Testing in Angular(7/8/9) Using Jasmine and Karma Part-2Unit Testing in Angular(7/8/9) Using Jasmine and Karma Part-2
Unit Testing in Angular(7/8/9) Using Jasmine and Karma Part-2
 
Test your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practiceTest your code like a pro - PHPUnit in practice
Test your code like a pro - PHPUnit in practice
 
100% Code Coverage - TDD mit Java EE
100% Code Coverage - TDD mit Java EE100% Code Coverage - TDD mit Java EE
100% Code Coverage - TDD mit Java EE
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
PHPUnit testing to Zend_Test
PHPUnit testing to Zend_TestPHPUnit testing to Zend_Test
PHPUnit testing to Zend_Test
 

Ähnlich wie Introduction To Testing With Perl

Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
Yi-Huan Chan
 
(C++) Change the following program so that it uses a dynamic array i.pdf
(C++) Change the following program so that it uses a dynamic array i.pdf(C++) Change the following program so that it uses a dynamic array i.pdf
(C++) Change the following program so that it uses a dynamic array i.pdf
f3apparelsonline
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
mfrost503
 

Ähnlich wie Introduction To Testing With Perl (20)

Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!
 
Effective Unit Test Style Guide
Effective Unit Test Style GuideEffective Unit Test Style Guide
Effective Unit Test Style Guide
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
 
Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
(C++) Change the following program so that it uses a dynamic array i.pdf
(C++) Change the following program so that it uses a dynamic array i.pdf(C++) Change the following program so that it uses a dynamic array i.pdf
(C++) Change the following program so that it uses a dynamic array i.pdf
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
PL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be FunPL/SQL Unit Testing Can Be Fun
PL/SQL Unit Testing Can Be Fun
 
New Features Of Test Unit 2.x
New Features Of Test Unit 2.xNew Features Of Test Unit 2.x
New Features Of Test Unit 2.x
 
Deixe o teste infectar você
Deixe o teste infectar vocêDeixe o teste infectar você
Deixe o teste infectar você
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 

Mehr von joshua.mcadams

Open Flash Chart And Perl
Open Flash Chart And PerlOpen Flash Chart And Perl
Open Flash Chart And Perl
joshua.mcadams
 

Mehr von joshua.mcadams (9)

Open Flash Chart And Perl
Open Flash Chart And PerlOpen Flash Chart And Perl
Open Flash Chart And Perl
 
Thank A Cpan Contributor Today
Thank A Cpan Contributor TodayThank A Cpan Contributor Today
Thank A Cpan Contributor Today
 
Utility Modules That You Should Know About
Utility Modules That You Should Know AboutUtility Modules That You Should Know About
Utility Modules That You Should Know About
 
YAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl CodingYAPC::NA 2007 - Epic Perl Coding
YAPC::NA 2007 - Epic Perl Coding
 
YAPC::NA 2007 - Customizing And Extending Perl Critic
YAPC::NA 2007 - Customizing And Extending Perl CriticYAPC::NA 2007 - Customizing And Extending Perl Critic
YAPC::NA 2007 - Customizing And Extending Perl Critic
 
YAPC::NA 2007 - An Introduction To Perl Critic
YAPC::NA 2007 - An Introduction To Perl CriticYAPC::NA 2007 - An Introduction To Perl Critic
YAPC::NA 2007 - An Introduction To Perl Critic
 
Extending Perl Critic
Extending Perl CriticExtending Perl Critic
Extending Perl Critic
 
An Introduction To Perl Critic
An Introduction To Perl CriticAn Introduction To Perl Critic
An Introduction To Perl Critic
 
Lightning Talk: An Introduction To Scrum
Lightning Talk: An Introduction To ScrumLightning Talk: An Introduction To Scrum
Lightning Talk: An Introduction To Scrum
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 

Introduction To Testing With Perl

  • 4. introduction Testing seems like a very simple concept. Testing is the process of doing something, collecting the results of what you just did, and then verifying that the results are what you expected. Even simpler, software testing can be reduced to saying that given a known input, an expected output is produced. Even with a simple definition, testing is a very complex subject that is continually argued about.
  • 5. introduction Unit tests are tests, so they take the result of some action and validate that result against what was expected. Unit tests check small components of your system to make sure that they are functioning correctly. An automated test is a test that doesn’t necessarily require any human intervention in order to run. In Perl, you get a nice automated unit testing system for free with prove, Test::Harness, Test::More, ExtUtils::MakeMaker, Module::Build, and friends.
  • 6. example problem Throughout the talk, we’ll be creating a Perl module that will calculate percentage of ownership for an owner in a condo. The percentages are used for important things like association elections and assessments, so they have to be correct or lawyers will get involved.
  • 7. example problem The formula works by determining the percentage of the building that an individual owns in proportion to the total livable space. Common areas are not included. The trick is that the actual square footage of any unit is weighted using multiplier. Each floor up adds an extra hundredth to the weight. For instance, a 600 square foot unit on the 11th floor would be weighted at 600 * 1.11 = 666.
  • 8. example problem Don’t worry about units that span multiple floors. Ninety-nine floors are the most that any building can have. Don’t worry about matching up owners who have multiple units. Underground floors all get a weight of zero, no matter how many levels down they actually are.
  • 9. working example 1 use warnings; 2 use strict; 3 use Test::More tests => 1; 4 5 BEGIN { use_ok('PercentOwnership'); }
  • 10. working example --(0)> prove t/percent_ownership.t t/percent_ownership.... # Failed test 'use PercentOwnership;' # at t/percent_ownership.t line 5. # Tried to use 'PercentOwnership'. # Error: Can't locate PercentOwnership.pm in @INC (@INC contains: ...) at (eval 3) line 2. # BEGIN failed--compilation aborted at t/percent_ownership.t line 5. # Looks like you failed 1 test of 1. t/percent_ownership....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 1 Failed 1/1 tests, 0.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed ------------------------------------------------------------------------------- t/percent_ownership.t 1 256 1 1 100.00% 1 Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
  • 11. working example 1 package PercentOwnership; 2 3 use warnings; 4 use strict; 5 6 1;
  • 12. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership....ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.04 cusr + 0.02 csys = 0.06 CPU)
  • 13. working example 1 use warnings; 2 use strict; 3 use Test::More tests => 2; 4 5 BEGIN { use_ok('PercentOwnership') } 6 7 can_ok( 'PercentOwnership', 'new' );
  • 14. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership.... # Failed test 'PercentOwnership->can('new')' # at t/percent_ownership.t line 7. # PercentOwnership->can('new') failed # Looks like you failed 1 test of 2. t/percent_ownership....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 2 Failed 1/2 tests, 50.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed -------------------------------------------------------------------------- t/percent_ownership.t 1 256 2 1 50.00% 2 Failed 1/1 test scripts, 0.00% okay. 1/2 subtests failed, 50.00% okay.
  • 15. working example 1 package PercentOwnership; 2 3 use warnings; 4 use strict; 5 6 sub new {} 7 8 1;
  • 16. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership....ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.04 cusr + 0.02 csys = 0.06 CPU)
  • 17. working example 3 use Test::More tests => 3; 4 5 BEGIN { use_ok('PercentOwnership') } 6 7 can_ok( 'PercentOwnership', 'new' ); 8 my $po = PercentOwnership->new(); 9 isa_ok( $po, 'PercentOwnership' );
  • 18. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership.... # Failed test 'The object isa PercentOwnership' # at t/percent_ownership.t line 9. # The object isn't defined # Looks like you failed 1 test of 3. t/percent_ownership....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 3 Failed 1/3 tests, 66.67% okay Failed Test Stat Wstat Total Fail Failed List of Failed ----------------------------------------------------------------------- t/percent_ownership.t 1 256 3 1 33.33% 3 Failed 1/1 test scripts, 0.00% okay. 1/3 subtests failed, 66.67% okay.
  • 19. working example 1 package PercentOwnership; 2 3 use warnings; 4 use strict; 5 6 sub new { 7 my ($class) = @_; 8 my $self = bless {}, $class; 9 return $self; 10 } 11 12 1;
  • 20. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership....ok All tests successful. Files=1, Tests=3, 0 wallclock secs ( 0.04 cusr + 0.02 csys = 0.06 CPU)
  • 21. working example 3 use Test::More tests => 4; 4 5 BEGIN { use_ok('PercentOwnership') }; 6 7 can_ok( 'PercentOwnership', 'new' ); 8 my $po = PercentOwnership->new(); 9 isa_ok($po, 'PercentOwnership'); 10 11 can_ok( $po, 'add_unit' );
  • 22. working example 6 sub new { 7 my ($class) = @_; 8 my $self = bless {}, $class; 9 return $self; 10 } 11 12 sub add_unit {}
  • 23. working example 11 can_ok( $po, qw(add_unit percent_ownership) ); 12 13 $po->add_unit( 14 unit_number => 101, 15 square_footage => 450, 16 floor => 1, 17 );
  • 24. working example 6 sub new { 7 my ($class) = @_; 8 my $self = bless {}, $class; 9 return $self; 10 } 11 12 sub add_unit {} 13 14 sub percent_ownership {}
  • 25. working example 11 can_ok( $po, qw(add_unit percent_ownership) ); 12 13 $po->add_unit( 14 unit_number => 101, 15 square_footage => 450, 16 floor => 1, 17 ); 18 19 is( $po->percent_ownership( unit_number => 101 ) , 100, 'single unit condo' );
  • 26. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership.... # Failed test 'single unit condo' # at t/percent_ownership.t line 19. # got: undef # expected: '100' # Looks like you planned 4 tests but ran 1 extra. # Looks like you failed 1 test of 5 run. t/percent_ownership....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 5 Failed 1/4 tests, 75.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed ----------------------------------------------------------------------- t/percent_ownership.t 1 256 4 2 50.00% 5 Failed 1/1 test scripts, 0.00% okay. 0/4 subtests failed, 100.00% okay.
  • 27. working example 1 package PercentOwnership; 2 3 use warnings; 4 use strict; 5 6 sub new { 7 my ($class) = @_; 8 my $self = bless {}, $class; 9 return $self; 10 } 11 12 sub add_unit { } 13 14 sub percent_ownership { return 100; } 15 16 1;
  • 28. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership....ok All tests successful. Files=1, Tests=5, 0 wallclock secs ( 0.04 cusr + 0.02 csys = 0.06 CPU)
  • 29. working example 9 SINGLE_UNIT: { 10 my $po = PercentOwnership->new(); 11 isa_ok( $po, 'PercentOwnership' ); 12 13 can_ok( $po, qw(add_unit percent_ownership) ); 14 15 $po->add_unit( 16 unit_number => 101, 17 square_footage => 450, 18 floor => 1, 19 ); 20 21 is( $po->percent_ownership( unit_number => 101 ), 100, 22 'single unit condo' ); 23 }
  • 30. working example 25 TWO_UNITS: { 26 my $po = PercentOwnership->new(); 27 isa_ok( $po, 'PercentOwnership' ); 28 29 can_ok( $po, qw(add_unit percent_ownership) ); 30 31 $po->add_unit( 32 unit_number => 101, 33 square_footage => 450, 34 floor => 1, 35 ); 36 37 $po->add_unit( 38 unit_number => 102, 39 square_footage => 450, 40 floor => 1, 41 ); 42 43 is( $po->percent_ownership( unit_number => 101 ), 50, 44 'single unit condo' ); 45 }
  • 31. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership....NOK 8 # Failed test 'single unit condo' # at t/percent_ownership.t line 43. # got: '100' # expected: '50' # Looks like you failed 1 test of 8. t/percent_ownership....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 8 Failed 1/8 tests, 87.50% okay Failed Test Stat Wstat Total Fail Failed List of Failed ----------------------------------------------------------------------- t/percent_ownership.t 1 256 8 1 12.50% 8 Failed 1/1 test scripts, 0.00% okay. 1/8 subtests failed, 87.50% okay.
  • 32. working example 5 use List::Util qw(sum); ... 13 sub add_unit { 14 my ( $self, %unit_info ) = @_; 15 16 $self->{unit_info}->{ $unit_info{unit_number} } = %unit_info; 17 } 18 19 sub percent_ownership { 20 my ( $self, %args ) = @_; 21 22 my $building_size = sum map { $self->{unit_info}->{$_}->{square_footage} } 23 keys %{ $self->{unit_info} }; 24 25 my $unit_size = 26 $self->{unit_info}->{ $args{unit_number} }->{square_footage}; 27 28 return sprintf( quot;%0.4fquot;, $unit_size / $building_size ) * 100; 29 }
  • 33. working example --(0)> prove -Ilib t/percent_ownership.t t/percent_ownership....ok All tests successful. Files=1, Tests=8, 1 wallclock secs ( 0.06 cusr + 0.02 csys = 0.08 CPU)
  • 34. tap 1..8 ok 1 - use PercentOwnership; ok 2 - PercentOwnership->can('new') ok 3 - The object isa PercentOwnership ok 4 - PercentOwnership->can(...) ok 5 - single unit condo ok 6 - The object isa PercentOwnership ok 7 # skip I'm lazy not ok 8 - single unit condo # TODO I just havn't figured it out yet # Failed (TODO) test 'single unit condo' # at t/percent_ownership.t line 45. # got: '50' # expected: '51'
  • 36. test::class 1 package TestPercentOwnership; 2 3 use warnings; 4 use strict; 5 use base qw(Test::Class); 6 use Test::More; 7 8 __PACKAGE__->runtests unless caller; 9 10 sub startup_test : Test( startup => 2 ) { 11 use_ok('PercentOwnership'); 12 can_ok( 'PercentOwnership', 'new' ); 13 } 14 15 1;
  • 37. test::class 15 sub single_unit : Test(3) { 16 my ($self) = @_; 17 my $po = PercentOwnership->new(); 18 isa_ok( $po, 'PercentOwnership' ); 19 can_ok( 'PercentOwnership' , qw(add_unit percent_ownership) ); 20 21 $po->add_unit( 22 unit_number => 101, 23 square_footage => 450, 24 floor => 1, 25 ); 26 27 is( $po->percent_ownership( unit_number => 101 ), 100, 28 'single unit condo' ); 29 }
  • 38. test::differences 3 use Test::More qw(no_plan); 4 5 my $expected = 'This is a multiline 6 string of text 7 that is not the easiest thing to 8 display.'; 9 10 my $got = $expected; 11 substr($got, 12, 1) = 'i'; 12 13 is $got, $expected, 'The are who we thought they were';
  • 39. test::differences --(0)> prove scalar_is_deeply.t is_deeply.... # Failed test 'The are who we thought they were' # at is_deeply.t line 13. # got: 'This is a muitiline # string of text # that is not the easiest thing to # display.' # expected: 'This is a multiline # string of text # that is not the easiest thing to # display.' # Looks like you failed 1 test of 1. is_deeply....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 1 Failed 1/1 tests, 0.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed ------------------------------------------------------------------------------- is_deeply.t 1 256 1 1 100.00% 1 Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
  • 40. test::differences 3 use Test::More qw(no_plan); 4 use Test::Differences; 5 6 my $expected = 'This is a multiline 7 string of text 8 that is not the easiest thing to 9 display.'; 10 11 my $got = $expected; 12 substr($got, 12, 1) = 'i'; 13 14 eq_or_diff $got, $expected, 'They are who we thought they were';
  • 41. test::differences --(0)> prove scalar_test_differences.t test_differences....NOK 1 # Failed test 'They are who we thought they were' # at test_differences.t line 14. # +---+----------------------------------+----------------------------------+ # | Ln|Got |Expected | # +---+----------------------------------+----------------------------------+ # * 1|This is a muitiline |This is a multiline * # | 2|string of text |string of text | # | 3|that is not the easiest thing to |that is not the easiest thing to | # | 4|display. |display. | # +---+----------------------------------+----------------------------------+ # Looks like you failed 1 test of 1. test_differences....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 1 Failed 1/1 tests, 0.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed ------------------------------------------------------------------------------- test_differences.t 1 256 1 1 100.00% 1 Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
  • 42. test::differences 1 use warnings; 2 use strict; 3 use Test::More qw(no_plan); 4 5 my $expected = { name => 'Josh', pets => [qw( ella ginger )] }; 6 my $got = bless {%$expected}, 'Person'; 7 $got->{name} = 'Heather'; 8 9 is $got, $expected, 'Structures are different';
  • 43. test::differences --(0)> prove ref_is_deeply.t ref_is_deeply.... # Failed test 'Structures are different' # at ref_is_deeply.t line 9. # got: 'Person=HASH(0x183beb8)' # expected: 'HASH(0x183be40)' # Looks like you failed 1 test of 1. ref_is_deeply....dubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 1 Failed 1/1 tests, 0.00% okay Failed Test Stat Wstat Total Fail Failed List of Failed ----------------------------------------------------------------------- ref_is_deeply.t 1 256 1 1 100.00% 1 Failed 1/1 test scripts, 0.00% okay. 1/1 subtests failed, 0.00% okay.
  • 44. test::differences 1 use warnings; 2 use strict; 3 use Test::More qw(no_plan); 4 use Test::Differences; 5 6 my $expected = { name => 'Josh', pets => [qw( ella ginger )] }; 7 my $got = bless {%$expected}, 'Person'; 8 $got->{name} = 'Heather'; 9 10 eq_or_diff $got, $expected, 'Structures are different';
  • 45. test::differences --(0)> perl ref_test_differences.t not ok 1 - Structures are different # Failed test 'Structures are different' # at ref_test_differences.t line 10. # +----+----------------------+-------------------+ # | Elt|Got |Expected | # +----+----------------------+-------------------+ # * 0|bless( { |{ * # * 1| name => 'Heather', | name => 'Josh', * # | 2| pets => [ | pets => [ | # | 3| 'ella', | 'ella', | # | 4| 'ginger' | 'ginger' | # | 5| ] | ] | # * 6|}, 'Person' ) |} * # +----+----------------------+-------------------+ 1..1 # Looks like you failed 1 test of 1.
  • 46. test::deep 3 use Test::More qw(no_plan); 4 use Test::Deep; 5 6 my $obj = bless { name => 'x' }, 'Thing'; 7 8 cmp_deeply( $obj, 9 all( isa('Thing') , noclass( subhashof( { name => 'x', rank => 'y' } ) ) ) ); 10 cmp_deeply( $obj, any( isa('Thing'), isa('OtherThing') ) );
  • 47. test::mockobject 3 use Test::More qw(no_plan); 4 use Test::MockObject; 5 6 my $mock = Test::MockObject->new(); 7 isa_ok( $mock, 'Test::MockObject' ); 8 9 $mock->set_isa( 'DBI', 'DBIx::Class' ); 10 isa_ok( $mock, 'DBIx::Class' ); 11 isa_ok( $mock, 'DBI' );