SlideShare ist ein Scribd-Unternehmen logo
1 von 45
Downloaden Sie, um offline zu lesen
  OO tests for OO code
       Nice performance boost
       Easy-to-organize test suites




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  Plenty!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
use     strict;!
     use     warnings;!
     use     Test::Exception 0.88;!
     use     Test::Differences 0.500;!
     use     Test::Deep 0.106;!
     use     Test::Warn 0.11;!
     use     Test::More 0.88;!

     use parent 'My::Test::Class’;!
     sub some_test : Tests { ... }!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
use Test::Class::Most!
         parent => 'My::Test::Class’;!

     sub some_test : Tests { ... }!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
lib/!
     | Person/!
     | `-- Employee.pm!
     `-- Person.pm!

     t/!
     | lib/!
     | | My/!
     | | | Test/!
     | | | `-- Class.pm!
     | | TestsFor/!
     | | | Person/!
     | | | `-- Employee.pm!
     | | `-- Person.pm!
     `-- test_class_tests.t!


http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package My::Test::Class;!
     use Test::Class::Most !
         attributes => ['class'];!

     INIT { Test::Class->runtests }!

     sub       startup               :    Tests(startup)       {…}!
     sub       setup                 :    Tests(setup)         {}!
     sub       teardown              :    Tests(teardown)      {}!
     sub       shutdown              :    Tests(shutdown)      {}!

     1;!

http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package My::Test::Class;!
     use Test::Class::Most !
         attributes => ['class'];!

     INIT { Test::Class->runtests }!

     sub       startup               :    Tests(startup)       {…}!
     sub       setup                 :    Tests(setup)         {}!
     sub       teardown              :    Tests(teardown)      {}!
     sub       shutdown              :    Tests(shutdown)      {}!

     1;!

http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package My::Test::Class;!
     use Test::Class::Most !
         attributes => ['class'];!

     INIT { Test::Class->runtests }!

     sub       startup               :    Tests(startup)       {…}!
     sub       setup                 :    Tests(setup)         {}!
     sub       teardown              :    Tests(teardown)      {}!
     sub       shutdown              :    Tests(shutdown)      {}!

     1;!

http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package My::Test::Class;!
     use Test::Class::Most !
         attributes => ['class'];!

     INIT { Test::Class->runtests }!

     sub       startup               :    Tests(startup)       {…}!
     sub       setup                 :    Tests(setup)         {}!
     sub       teardown              :    Tests(teardown)      {}!
     sub       shutdown              :    Tests(shutdown)      {}!

     1;!

http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
sub startup : Tests(startup)                              {!
         my $test = shift;!
         return if $test->class;!

               my $class = ref $test;!
               $class    =~ s/^TestsFor:://;!

               eval "use $class";!
               die $@ if $@;!

               $test->class($class);!
     }!

http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package Person;

     use Moose;!

     has ‘first_name’ => ( is => 'ro', isa => 'Str' );!
     has ‘last_name’ => ( is => 'ro', isa => 'Str' );!

     sub full_name {!
         my $self = shift;!
         return $self->first_name . ' ' !
           . $self->last_name;!
     }!

     1;!

http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!

             can_ok $class, 'new';
             ok my $person = $class->new, !
               '... and the constructor should succeed';!
             isa_ok $person, $class, !
               '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!
         can_ok $class, 'new';
         ok my $person = $class->new, !
           '... and the constructor should succeed';!
         isa_ok $person, $class, !
           '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!
         can_ok $class, 'new';
         ok my $person = $class->new, !
           '... and the constructor should succeed';!
         isa_ok $person, $class, !
           '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!
         can_ok $class, 'new';
         ok my $person = $class->new, !
           '... and the constructor should succeed';!
         isa_ok $person, $class, !
           '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!
         can_ok $class, 'new';
         ok my $person = $class->new, !
           '... and the constructor should succeed';!
         isa_ok $person, $class, !
           '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!
         can_ok $class, 'new';
         ok my $person = $class->new, !
           '... and the constructor should succeed';!
         isa_ok $person, $class, !
           '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!

     use Test::Class::Most parent =>'My::Test::Class';!

     sub constructor : Tests(3) {!
         my $test = shift;!
         my $class = $test->class;!
         can_ok $class, 'new';
         ok my $person = $class->new, !
           '... and the constructor should succeed';!
         isa_ok $person, $class, !
           '... and the object it returns';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
prove -lv -It/lib !
       t/lib/TestsFor/Person.pm !

     # INIT { Test::Class->runtests }!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
t/TestsFor/Person.pm .. # !
     # TestsFor::Person->constructor!

     1..3!
     ok 1 - Person->can('new')!
     ok 2 - ... and the constructor should succeed!
     ok 3 - ... and the object it returns isa
        Person!
     ok!
     All tests successful.!
     Files=1, Tests=3, 0 wallclock secs!
     Result: PASS!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person;!
     Use Test::Class::Most parent => ‘My::Test::Class’;!
     sub constructor : Tests(3) { … }!

     sub full_name : Tests(4) {
         my $test   = shift;!
         my $person = $test->class->new(!
             first_name => 'Adrian',!
             last_name => 'Howard',!
         );!

           is $person->first_name, 'Adrian', 'first_name correct';!
           is $person->last_name, 'Howard', 'last_name correct';!

           can_ok $person, 'full_name';!
           is $person->full_name, 'Adrian Howard',!
             '... and it should return the correct fullname';!
     }!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
$ prove –vl -It/lib t/TestsFor/Person.pm!
     t/TestsFor/Person.pm .. # !
     # TestsFor::Person->constructor!
     1..7!
     ok 1 - Person->can('new’)!
     ok 2 - ... and the constructor should succeed!
     ok 3 - ... and the object it returns isa Person!
     # !
     # TestsFor::Person->full_name!
     ok 4 - first_name correct!
     ok 5 - last_name correct!
     ok 6 - Person->can('full_name')!
     ok 7 - ... and it should return the correct fullname!
     ok!
     All tests successful.!
     Files=1, Tests=7, 0 wallclock secs!
     Result: PASS!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package Person::Employee;

     use Moose;!
     extends 'Person';!

     has ‘employee_number’ => ( !
       is => ‘ro’, !
       isa => ‘Int’,!
     );!

     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Person::Employee;!

     use Test::Class::Most parent => 'TestsFor::Person';!

     sub employee_number : Tests(2) {
         my $test      = shift;!
         my $employee = $test->class->new(!
             first_name       => 'John',!
             last_name        => 'Public',!
             employee_number => 17,!
         );!
         can_ok $employee, 'employee_number’;!
         is $employee->employee_number, 17, !
           '... the employee number is correct';!
     }!
     1;!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
t/TestsFor/Person/Employee.pm .. # !                      # !
     # TestsFor::Person::Employee->constructor!                # TestsFor::Person->constructor!
                                                               ok 10 - Person->can('new')!
     1..16!                                                    ok 11 - ... and the constructor should
     ok 1 - Person::Employee->can('new')!                            succeed!
     ok 2 - ... and the constructor should succeed!            ok 12 - ... and the object it returns isa
     ok 3 - ... and the object it returns isa                        Person!
           Person::Employee!                                   # !
     # !                                                       # TestsFor::Person->full_name!
     # TestsFor::Person::Employee->employee_number!            ok 13 - first_name correct!
     ok 4 - Person::Employee-                                  ok 14 - last_name correct!
           >can('employee_number')!                            ok 15 - Person->can('full_name')!
     ok 5 - ... the employee number is correct!                ok 16 - ... and it should return the correct
     # !                                                             fullname!
     # TestsFor::Person::Employee->full_name!                  ok!
     ok 6 - first_name correct!                                All tests successful.!
     ok 7 - last_name correct!                                 Files=1, Tests=16, 0 wallclock secs!
     ok 8 - Person::Employee->can('full_name')!                Result: PASS!
     ok 9 - ... and it should return the correct
           fullname!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
t/TestsFor/Person/Employee.pm .. # !                      # !
     # TestsFor::Person::Employee->constructor!                # TestsFor::Person->constructor!
                                                               ok 10 - Person->can('new')!
     1..16!                                                    ok 11 - ... and the constructor should
     ok 1 - Person::Employee->can('new')!                            succeed!
     ok 2 - ... and the constructor should succeed!            ok 12 - ... and the object it returns isa
     ok 3 - ... and the object it returns isa                        Person!
           Person::Employee!                                   # !
     # !                                                       # TestsFor::Person->full_name!
     # TestsFor::Person::Employee->employee_number!            ok 13 - first_name correct!
     ok 4 - Person::Employee-                                  ok 14 - last_name correct!
           >can('employee_number')!                            ok 15 - Person->can('full_name')!
     ok 5 - ... the employee number is correct!                ok 16 - ... and it should return the correct
     # !                                                             fullname!
     # TestsFor::Person::Employee->full_name!                  ok!
     ok 6 - first_name correct!                                All tests successful.!
     ok 7 - last_name correct!                                 Files=1, Tests=16, 0 wallclock secs!
     ok 8 - Person::Employee->can('full_name')!                Result: PASS!
     ok 9 - ... and it should return the correct
           fullname!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
t/TestsFor/Person/Employee.pm .. # !                      # !
     # TestsFor::Person::Employee->constructor!                # TestsFor::Person->constructor!
                                                               ok 10 - Person->can('new')!
     1..16!                                                    ok 11 - ... and the constructor should
     ok 1 - Person::Employee->can('new')!                            succeed!
     ok 2 - ... and the constructor should succeed!            ok 12 - ... and the object it returns isa
     ok 3 - ... and the object it returns isa                        Person!
           Person::Employee!                                   # !
     # !                                                       # TestsFor::Person->full_name!
     # TestsFor::Person::Employee->employee_number!            ok 13 - first_name correct!
     ok 4 - Person::Employee-                                  ok 14 - last_name correct!
           >can('employee_number')!                            ok 15 - Person->can('full_name')!
     ok 5 - ... the employee number is correct!                ok 16 - ... and it should return the correct
     # !                                                             fullname!
     # TestsFor::Person::Employee->full_name!                  ok!
     ok 6 - first_name correct!                                All tests successful.!
     ok 7 - last_name correct!                                 Files=1, Tests=16, 0 wallclock secs!
     ok 8 - Person::Employee->can('full_name')!                Result: PASS!
     ok 9 - ... and it should return the correct
           fullname!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
t/TestsFor/Person/Employee.pm .. # !                      # !
     # TestsFor::Person::Employee->constructor!                # TestsFor::Person->constructor!
                                                               ok 10 - Person->can('new')!
     1..16!                                                    ok 11 - ... and the constructor should
     ok 1 - Person::Employee->can('new')!                            succeed!
     ok 2 - ... and the constructor should succeed!            ok 12 - ... and the object it returns isa
     ok 3 - ... and the object it returns isa                        Person!
           Person::Employee!                                   # !
     # !                                                       # TestsFor::Person->full_name!
     # TestsFor::Person::Employee->employee_number!            ok 13 - first_name correct!
     ok 4 - Person::Employee-                                  ok 14 - last_name correct!
           >can('employee_number')!                            ok 15 - Person->can('full_name')!
     ok 5 - ... the employee number is correct!                ok 16 - ... and it should return the correct
     # !                                                             fullname!
     # TestsFor::Person::Employee->full_name!                  ok!
     ok 6 - first_name correct!                                All tests successful.!
     ok 7 - last_name correct!                                 Files=1, Tests=16, 0 wallclock secs!
     ok 8 - Person::Employee->can('full_name')!                Result: PASS!
     ok 9 - ... and it should return the correct
           fullname!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
t/TestsFor/Person/Employee.pm .. # !                      # !
     # TestsFor::Person::Employee->constructor!                # TestsFor::Person->constructor!
                                                               ok 10 - Person->can('new')!
     1..16!                                                    ok 11 - ... and the constructor should
     ok 1 - Person::Employee->can('new')!                            succeed!
     ok 2 - ... and the constructor should succeed!            ok 12 - ... and the object it returns isa
     ok 3 - ... and the object it returns isa                        Person!
           Person::Employee!                                   # !
     # !                                                       # TestsFor::Person->full_name!
     # TestsFor::Person::Employee->employee_number!            ok 13 - first_name correct!
     ok 4 - Person::Employee-                                  ok 14 - last_name correct!
           >can('employee_number')!                            ok 15 - Person->can('full_name')!
     ok 5 - ... the employee number is correct!                ok 16 - ... and it should return the correct
     # !                                                             fullname!
     # TestsFor::Person::Employee->full_name!                  ok!
     ok 6 - first_name correct!                                All tests successful.!
     ok 7 - last_name correct!                                 Files=1, Tests=16, 0 wallclock secs!
     ok 8 - Person::Employee->can('full_name')!                Result: PASS!
     ok 9 - ... and it should return the correct
           fullname!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
sub startup : Tests(startup)                              {!
         my $test = shift;!
         return if $test->class;!

               my $class = ref $test;!
               $class    =~ s/^TestsFor:://;!

               eval "use $class";!
               die $@ if $@;!

               $test->class($class);!
     }!
http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  TestsFor::Person::Employee inherits
        TestsFor::Person’s tests
       We don’t hard-code the class name
       Inherited test methods rock!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
Attribute Name                                            Phase
     Tests(startup)!                                           When the test class starts
     Tests(setup)!                                             Before each test method
     Tests(teardown)!                                          After each test method
     Tests(shutdown)!                                          When the test class finishes




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
     Connect to a database (often in startup)
          Set up fixtures/transactions (setup)
          Clean fixtures/rollbacks (teardown)
          Disconnect from database (shutdown)
          (They’re a better place for object construction)




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Customer;!                              package TestsFor::Person::Employee;!


     use Test::Class::Most!                                    use Test::Class::Most!
         parent     => ‘My::Test::Class’,!                         parent    => ‘TestsFor::Customer’,!
         attributes => [‘dbh’];!                                   attributes => [‘employee’];!


     sub aaa_connect_to_db : Tests(setup) {!                   sub bbb_employee : Tests(setup) {!
         my $test = shift;!                                        my $test     = shift;!
         my $dbh = DBI->connect(…);!                               my $employee = $test->dbh->…;!
         # or $test->{dbh} = $dbh;!                                $test->employee($employee);!
         $test->dbh($dbh);!                                    }!
     }!
                                                               sub kill_employee : Tests {!
     sub some_test : Tests {!                                      my $test     = shift;!
         my $test = shift;!                                        my $employee = $test->employee;!
         my $dbh = $test->dbh;!                                    can_ok( $employee, ‘suffocate’ );!
     …!



http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Customer;!                              package TestsFor::Person::Employee;!


     use Test::Class::Most!                                    use Test::Class::Most!
         parent     => ‘My::Test::Class’,!                         parent    => ‘TestsFor::Customer’,!
         attributes => [‘dbh’];!                                   attributes => [‘employee’];!


     sub aaa_connect_to_db : Tests(setup) {!                   sub bbb_employee : Tests(setup) {!
         my $test = shift;!                                        my $test     = shift;!
         my $dbh = DBI->connect(…);!                               my $employee = $test->dbh->…;!
         # or $test->{dbh} = $dbh;!                                $test->employee($employee);!
         $test->dbh($dbh);!                                    }!
     }!
                                                               sub kill_employee : Tests {!
     sub some_test : Tests {!                                      my $test     = shift;!
         my $test = shift;!                                        my $employee = $test->employee;!
         my $dbh = $test->dbh;!                                    can_ok( $employee, ‘suffocate’ );!
     …!



http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
package TestsFor::Customer;!                              package TestsFor::Person::Employee;!


     use Test::Class::Most!                                    use Test::Class::Most!
         parent     => ‘My::Test::Class’,!                         parent    => ‘TestsFor::Customer’,!
         attributes => [‘dbh’];!                                   attributes => [‘employee’];!


     sub setup : Tests(setup) {!                               sub setup : Tests(setup) {!
         my $test = shift;!                                        my $test = shift;!
         my $dbh = DBI->connect(…);!                               $test->SUPER::setup;!
         # or $test->{dbh} = $dbh;!                                my $employee = $test->dbh->…;!
         $test->dbh($dbh);!                                        $test->employee($employee);!
     }!                                                        }!


     sub some_test : Tests {!                                  sub kill_employee : Tests {!
         my $test = shift;!                                        my $test     = shift;!
         my $dbh = $test->dbh;!                                    my $employee = $test->employee;!
     …!                                                            can_ok( $employee, ‘suffocate’ );!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
Before Tests                                         After Tests
     sub startup:Test(startup) {!                              sub teardown:Test(teardown){!
         my $test = shift;!                                        my $test = shift;!
         $test->SUPER::startup;!                                   # finish your teardown!
         # finish your startup!                                    $test->SUPER::teardown;!
     }!                                                        }!

     sub setup : Test(setup) {!                                sub shutdown:Test(shutdown){!
         my $test = shift;!                                        my $test = shift;!
         $test->SUPER::setup;!                                     # finish your shutdown!
         # finish your setup!                                      $test->SUPER::shutdown;!
     }!                                                        }!


http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
# t/test_class_tests.t!
     # Don’t Do This!!
     use lib ‘t/lib’;!

     use TestsFor::Person;!
     use TestsFor::Person::Employee;!

     Test::Class->runtests;!



http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
# Don’t Do This because you’ll forget one!!
     use lib ‘t/lib’;!
     use TestsFor::Person;!
     use TestsFor::Person::Employee;!
     use TestsFor::Database;!
     use TestsFor::PurchaseOrder;!
     use TestsFor::Alibi;!
     use TestsFor::Embezzlement;!
     use TestsFor::PaddingMySlides;!
     Test::Class->runtests;!


http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
# Do This!!
     use Test::Class::Load ‘t/lib’;!




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  Finds your test classes for you
       My example relies on
        INIT { Test::Class->runtests }
        in My::Test::Class.
       Run the test suite:
        prove -l t/test_class_tests.t!
       Or a single test class:
        prove -lv -It/lib t/TestsFor/Person.pm



http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
     Name test classes after their classes (if possible)
          Name test methods after their methods (if possible)
          … you can’t name a method new()!
          Create your own base test class
          … with stub test control methods
          Name test control methods after their attribute
          Don’t put tests in your test control methods
          Do not hardcode the name of the class to test!



http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
     Part 1: Getting started with Test::Class
          Part 2: Inheriting Test::Class tests
          Part 3: Making your testing life easier
          Part 4: Using test control methods
          Part 5: Test::Class Tricks




http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
     Beginning Perl, Wrox Press
          Introduction to Perl
          CPAN
          Modules
          Objects (Moose!)
          Testing
          PSGI+Plack
          DBIx::Class
          Catalyst
          And more!


http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass

Weitere ähnliche Inhalte

Was ist angesagt?

Nedap Rails Workshop
Nedap Rails WorkshopNedap Rails Workshop
Nedap Rails WorkshopAndre Foeken
 
Solr and Lucene at Etsy - By Gregg Donovan
Solr and Lucene at Etsy - By Gregg DonovanSolr and Lucene at Etsy - By Gregg Donovan
Solr and Lucene at Etsy - By Gregg Donovanlucenerevolution
 
Solr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg DonovanSolr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg DonovanGregg Donovan
 
Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2nottings
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in LaravelAhmed Yahia
 
Javascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyJavascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyThorsten Suckow-Homberg
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suckRoss Bruniges
 
Top 10 php classic traps confoo
Top 10 php classic traps confooTop 10 php classic traps confoo
Top 10 php classic traps confooDamien Seguy
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmineRubyc Slides
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, SematextSolr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, SematextLucidworks
 
Simulator customizing & testing for Xcode 9
Simulator customizing & testing for Xcode 9Simulator customizing & testing for Xcode 9
Simulator customizing & testing for Xcode 9Bongwon Lee
 
Porting Java To Scala
Porting Java To Scala Porting Java To Scala
Porting Java To Scala guestbfe8bf
 
Testing stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.checkTesting stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.checkEric Normand
 

Was ist angesagt? (20)

Nedap Rails Workshop
Nedap Rails WorkshopNedap Rails Workshop
Nedap Rails Workshop
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
Solr and Lucene at Etsy - By Gregg Donovan
Solr and Lucene at Etsy - By Gregg DonovanSolr and Lucene at Etsy - By Gregg Donovan
Solr and Lucene at Etsy - By Gregg Donovan
 
Solr & Lucene at Etsy
Solr & Lucene at EtsySolr & Lucene at Etsy
Solr & Lucene at Etsy
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
Solr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg DonovanSolr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg Donovan
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
 
Javascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the UglyJavascript - The Good, the Bad and the Ugly
Javascript - The Good, the Bad and the Ugly
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suck
 
Top 10 php classic traps confoo
Top 10 php classic traps confooTop 10 php classic traps confoo
Top 10 php classic traps confoo
 
Living with garbage
Living with garbageLiving with garbage
Living with garbage
 
Testing your javascript code with jasmine
Testing your javascript code with jasmineTesting your javascript code with jasmine
Testing your javascript code with jasmine
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, SematextSolr Anti-Patterns: Presented by Rafał Kuć, Sematext
Solr Anti-Patterns: Presented by Rafał Kuć, Sematext
 
Simulator customizing & testing for Xcode 9
Simulator customizing & testing for Xcode 9Simulator customizing & testing for Xcode 9
Simulator customizing & testing for Xcode 9
 
Porting Java To Scala
Porting Java To Scala Porting Java To Scala
Porting Java To Scala
 
Testing stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.checkTesting stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.check
 
Evolving Tests
Evolving TestsEvolving Tests
Evolving Tests
 

Andere mochten auch

(Seleniumcamp) Selenium RC for QA Engineer
(Seleniumcamp) Selenium RC for QA Engineer(Seleniumcamp) Selenium RC for QA Engineer
(Seleniumcamp) Selenium RC for QA EngineerYan Alexeenko
 
Selenium Page Objects101
Selenium Page Objects101Selenium Page Objects101
Selenium Page Objects101Adam Goucher
 
Reliable tests with selenium web driver
Reliable tests with selenium web driverReliable tests with selenium web driver
Reliable tests with selenium web driverPawelPabich
 
Funcargs & other fun with pytest
Funcargs & other fun with pytestFuncargs & other fun with pytest
Funcargs & other fun with pytestBrianna Laugher
 
Large scale automation with jenkins
Large scale automation with jenkinsLarge scale automation with jenkins
Large scale automation with jenkinsKohsuke Kawaguchi
 
JavaScript Testing VIA Selenium
JavaScript Testing VIA SeleniumJavaScript Testing VIA Selenium
JavaScript Testing VIA SeleniumAdam Christian
 
Testing at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce LabsTesting at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce LabsSauce Labs
 
JUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJohn Ferguson Smart Limited
 
Continuous Integration, the minimum viable product
Continuous Integration, the minimum viable productContinuous Integration, the minimum viable product
Continuous Integration, the minimum viable productJulian Simpson
 
Selenium Users Anonymous
Selenium Users AnonymousSelenium Users Anonymous
Selenium Users AnonymousDave Haeffner
 
Mobile Test Automation at eBay
Mobile Test Automation at eBayMobile Test Automation at eBay
Mobile Test Automation at eBayDominik Dary
 
Continuous Deployment - Lean LA
Continuous Deployment - Lean LAContinuous Deployment - Lean LA
Continuous Deployment - Lean LAAsh Maurya
 
Creating Maintainable Automated Acceptance Tests
Creating Maintainable Automated Acceptance TestsCreating Maintainable Automated Acceptance Tests
Creating Maintainable Automated Acceptance TestsJez Humble
 

Andere mochten auch (14)

(Seleniumcamp) Selenium RC for QA Engineer
(Seleniumcamp) Selenium RC for QA Engineer(Seleniumcamp) Selenium RC for QA Engineer
(Seleniumcamp) Selenium RC for QA Engineer
 
Selenium for Designers
Selenium for DesignersSelenium for Designers
Selenium for Designers
 
Selenium Page Objects101
Selenium Page Objects101Selenium Page Objects101
Selenium Page Objects101
 
Reliable tests with selenium web driver
Reliable tests with selenium web driverReliable tests with selenium web driver
Reliable tests with selenium web driver
 
Funcargs & other fun with pytest
Funcargs & other fun with pytestFuncargs & other fun with pytest
Funcargs & other fun with pytest
 
Large scale automation with jenkins
Large scale automation with jenkinsLarge scale automation with jenkins
Large scale automation with jenkins
 
JavaScript Testing VIA Selenium
JavaScript Testing VIA SeleniumJavaScript Testing VIA Selenium
JavaScript Testing VIA Selenium
 
Testing at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce LabsTesting at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce Labs
 
JUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit Tests
 
Continuous Integration, the minimum viable product
Continuous Integration, the minimum viable productContinuous Integration, the minimum viable product
Continuous Integration, the minimum viable product
 
Selenium Users Anonymous
Selenium Users AnonymousSelenium Users Anonymous
Selenium Users Anonymous
 
Mobile Test Automation at eBay
Mobile Test Automation at eBayMobile Test Automation at eBay
Mobile Test Automation at eBay
 
Continuous Deployment - Lean LA
Continuous Deployment - Lean LAContinuous Deployment - Lean LA
Continuous Deployment - Lean LA
 
Creating Maintainable Automated Acceptance Tests
Creating Maintainable Automated Acceptance TestsCreating Maintainable Automated Acceptance Tests
Creating Maintainable Automated Acceptance Tests
 

Ähnlich wie A Whirlwind Tour of Test::Class

The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Puppet
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'Gary Larizza
 
Testing With Test::Class
Testing With Test::ClassTesting With Test::Class
Testing With Test::ClassCurtis Poe
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl TechniquesDave Cross
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in RubyConFoo
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogrammingjoshbuddy
 
Intro To Moose
Intro To MooseIntro To Moose
Intro To MoosecPanel
 
Puppetizing Multitier Architecture - PuppetConf 2014
Puppetizing Multitier Architecture - PuppetConf 2014Puppetizing Multitier Architecture - PuppetConf 2014
Puppetizing Multitier Architecture - PuppetConf 2014Puppet
 
Introduction To Moose
Introduction To MooseIntroduction To Moose
Introduction To MooseMike Whitaker
 
How would you describe Swift in three words?
How would you describe Swift in three words?How would you describe Swift in three words?
How would you describe Swift in three words?Colin Eberhardt
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
Advanced modulinos trial
Advanced modulinos trialAdvanced modulinos trial
Advanced modulinos trialbrian d foy
 

Ähnlich wie A Whirlwind Tour of Test::Class (20)

The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
Doing the Refactor Dance - Making Your Puppet Modules More Modular - PuppetCo...
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'
 
Testing With Test::Class
Testing With Test::ClassTesting With Test::Class
Testing With Test::Class
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Metaprogramming in Ruby
Metaprogramming in RubyMetaprogramming in Ruby
Metaprogramming in Ruby
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9Hidden Gems of Ruby 1.9
Hidden Gems of Ruby 1.9
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Intro To Moose
Intro To MooseIntro To Moose
Intro To Moose
 
Puppetizing Multitier Architecture - PuppetConf 2014
Puppetizing Multitier Architecture - PuppetConf 2014Puppetizing Multitier Architecture - PuppetConf 2014
Puppetizing Multitier Architecture - PuppetConf 2014
 
Introduction To Moose
Introduction To MooseIntroduction To Moose
Introduction To Moose
 
How would you describe Swift in three words?
How would you describe Swift in three words?How would you describe Swift in three words?
How would you describe Swift in three words?
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Advanced modulinos trial
Advanced modulinos trialAdvanced modulinos trial
Advanced modulinos trial
 

Mehr von Curtis Poe

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
life-off-earth.pptx
life-off-earth.pptxlife-off-earth.pptx
life-off-earth.pptxCurtis Poe
 
Corinna-2023.pptx
Corinna-2023.pptxCorinna-2023.pptx
Corinna-2023.pptxCurtis Poe
 
Corinna Status 2022.pptx
Corinna Status 2022.pptxCorinna Status 2022.pptx
Corinna Status 2022.pptxCurtis Poe
 
Rummaging in the clOOset
Rummaging in the clOOsetRummaging in the clOOset
Rummaging in the clOOsetCurtis Poe
 
Rescuing a-legacy-codebase
Rescuing a-legacy-codebaseRescuing a-legacy-codebase
Rescuing a-legacy-codebaseCurtis Poe
 
Perl 6 For Mere Mortals
Perl 6 For Mere MortalsPerl 6 For Mere Mortals
Perl 6 For Mere MortalsCurtis Poe
 
Disappearing Managers, YAPC::EU 2014, Bulgaria, Keynote
Disappearing Managers, YAPC::EU 2014, Bulgaria, KeynoteDisappearing Managers, YAPC::EU 2014, Bulgaria, Keynote
Disappearing Managers, YAPC::EU 2014, Bulgaria, KeynoteCurtis Poe
 
How to Fake a Database Design
How to Fake a Database DesignHow to Fake a Database Design
How to Fake a Database DesignCurtis Poe
 
Are Managers An Endangered Species?
Are Managers An Endangered Species?Are Managers An Endangered Species?
Are Managers An Endangered Species?Curtis Poe
 
The Lies We Tell About Software Testing
The Lies We Tell About Software TestingThe Lies We Tell About Software Testing
The Lies We Tell About Software TestingCurtis Poe
 
A/B Testing - What your mother didn't tell you
A/B Testing - What your mother didn't tell youA/B Testing - What your mother didn't tell you
A/B Testing - What your mother didn't tell youCurtis Poe
 
Test::Class::Moose
Test::Class::MooseTest::Class::Moose
Test::Class::MooseCurtis Poe
 
Agile Companies Go P.O.P.
Agile Companies Go P.O.P.Agile Companies Go P.O.P.
Agile Companies Go P.O.P.Curtis Poe
 
Logic Progamming in Perl
Logic Progamming in PerlLogic Progamming in Perl
Logic Progamming in PerlCurtis Poe
 
Inheritance Versus Roles - The In-Depth Version
Inheritance Versus Roles - The In-Depth VersionInheritance Versus Roles - The In-Depth Version
Inheritance Versus Roles - The In-Depth VersionCurtis Poe
 
Inheritance Versus Roles
Inheritance Versus RolesInheritance Versus Roles
Inheritance Versus RolesCurtis Poe
 
Turbo Charged Test Suites
Turbo Charged Test SuitesTurbo Charged Test Suites
Turbo Charged Test SuitesCurtis Poe
 

Mehr von Curtis Poe (19)

How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
life-off-earth.pptx
life-off-earth.pptxlife-off-earth.pptx
life-off-earth.pptx
 
Corinna-2023.pptx
Corinna-2023.pptxCorinna-2023.pptx
Corinna-2023.pptx
 
Corinna Status 2022.pptx
Corinna Status 2022.pptxCorinna Status 2022.pptx
Corinna Status 2022.pptx
 
Rummaging in the clOOset
Rummaging in the clOOsetRummaging in the clOOset
Rummaging in the clOOset
 
Rescuing a-legacy-codebase
Rescuing a-legacy-codebaseRescuing a-legacy-codebase
Rescuing a-legacy-codebase
 
Perl 6 For Mere Mortals
Perl 6 For Mere MortalsPerl 6 For Mere Mortals
Perl 6 For Mere Mortals
 
Disappearing Managers, YAPC::EU 2014, Bulgaria, Keynote
Disappearing Managers, YAPC::EU 2014, Bulgaria, KeynoteDisappearing Managers, YAPC::EU 2014, Bulgaria, Keynote
Disappearing Managers, YAPC::EU 2014, Bulgaria, Keynote
 
How to Fake a Database Design
How to Fake a Database DesignHow to Fake a Database Design
How to Fake a Database Design
 
Are Managers An Endangered Species?
Are Managers An Endangered Species?Are Managers An Endangered Species?
Are Managers An Endangered Species?
 
The Lies We Tell About Software Testing
The Lies We Tell About Software TestingThe Lies We Tell About Software Testing
The Lies We Tell About Software Testing
 
A/B Testing - What your mother didn't tell you
A/B Testing - What your mother didn't tell youA/B Testing - What your mother didn't tell you
A/B Testing - What your mother didn't tell you
 
Test::Class::Moose
Test::Class::MooseTest::Class::Moose
Test::Class::Moose
 
Agile Companies Go P.O.P.
Agile Companies Go P.O.P.Agile Companies Go P.O.P.
Agile Companies Go P.O.P.
 
Econ101
Econ101Econ101
Econ101
 
Logic Progamming in Perl
Logic Progamming in PerlLogic Progamming in Perl
Logic Progamming in Perl
 
Inheritance Versus Roles - The In-Depth Version
Inheritance Versus Roles - The In-Depth VersionInheritance Versus Roles - The In-Depth Version
Inheritance Versus Roles - The In-Depth Version
 
Inheritance Versus Roles
Inheritance Versus RolesInheritance Versus Roles
Inheritance Versus Roles
 
Turbo Charged Test Suites
Turbo Charged Test SuitesTurbo Charged Test Suites
Turbo Charged Test Suites
 

Kürzlich hochgeladen

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
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 RobisonAnna Loughnan Colquhoun
 
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 Processorsdebabhi2
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
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 DevelopmentsTrustArc
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
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)wesley chun
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Kürzlich hochgeladen (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
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
 
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
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
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
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
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)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

A Whirlwind Tour of Test::Class

  • 1.
  • 2.   OO tests for OO code   Nice performance boost   Easy-to-organize test suites http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 4. use strict;! use warnings;! use Test::Exception 0.88;! use Test::Differences 0.500;! use Test::Deep 0.106;! use Test::Warn 0.11;! use Test::More 0.88;! use parent 'My::Test::Class’;! sub some_test : Tests { ... }! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 5. use Test::Class::Most! parent => 'My::Test::Class’;! sub some_test : Tests { ... }! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 6. lib/! | Person/! | `-- Employee.pm! `-- Person.pm! t/! | lib/! | | My/! | | | Test/! | | | `-- Class.pm! | | TestsFor/! | | | Person/! | | | `-- Employee.pm! | | `-- Person.pm! `-- test_class_tests.t! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 7. package My::Test::Class;! use Test::Class::Most ! attributes => ['class'];! INIT { Test::Class->runtests }! sub startup : Tests(startup) {…}! sub setup : Tests(setup) {}! sub teardown : Tests(teardown) {}! sub shutdown : Tests(shutdown) {}! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 8. package My::Test::Class;! use Test::Class::Most ! attributes => ['class'];! INIT { Test::Class->runtests }! sub startup : Tests(startup) {…}! sub setup : Tests(setup) {}! sub teardown : Tests(teardown) {}! sub shutdown : Tests(shutdown) {}! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 9. package My::Test::Class;! use Test::Class::Most ! attributes => ['class'];! INIT { Test::Class->runtests }! sub startup : Tests(startup) {…}! sub setup : Tests(setup) {}! sub teardown : Tests(teardown) {}! sub shutdown : Tests(shutdown) {}! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 10. package My::Test::Class;! use Test::Class::Most ! attributes => ['class'];! INIT { Test::Class->runtests }! sub startup : Tests(startup) {…}! sub setup : Tests(setup) {}! sub teardown : Tests(teardown) {}! sub shutdown : Tests(shutdown) {}! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 11. sub startup : Tests(startup) {! my $test = shift;! return if $test->class;! my $class = ref $test;! $class =~ s/^TestsFor:://;! eval "use $class";! die $@ if $@;! $test->class($class);! }! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 12. package Person; use Moose;! has ‘first_name’ => ( is => 'ro', isa => 'Str' );! has ‘last_name’ => ( is => 'ro', isa => 'Str' );! sub full_name {! my $self = shift;! return $self->first_name . ' ' ! . $self->last_name;! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 13. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 14. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 15. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 16. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 17. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 18. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 19. package TestsFor::Person;! use Test::Class::Most parent =>'My::Test::Class';! sub constructor : Tests(3) {! my $test = shift;! my $class = $test->class;! can_ok $class, 'new'; ok my $person = $class->new, ! '... and the constructor should succeed';! isa_ok $person, $class, ! '... and the object it returns';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 20. prove -lv -It/lib ! t/lib/TestsFor/Person.pm ! # INIT { Test::Class->runtests }! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 21. t/TestsFor/Person.pm .. # ! # TestsFor::Person->constructor! 1..3! ok 1 - Person->can('new')! ok 2 - ... and the constructor should succeed! ok 3 - ... and the object it returns isa Person! ok! All tests successful.! Files=1, Tests=3, 0 wallclock secs! Result: PASS! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 22. package TestsFor::Person;! Use Test::Class::Most parent => ‘My::Test::Class’;! sub constructor : Tests(3) { … }! sub full_name : Tests(4) { my $test = shift;! my $person = $test->class->new(! first_name => 'Adrian',! last_name => 'Howard',! );! is $person->first_name, 'Adrian', 'first_name correct';! is $person->last_name, 'Howard', 'last_name correct';! can_ok $person, 'full_name';! is $person->full_name, 'Adrian Howard',! '... and it should return the correct fullname';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 23. $ prove –vl -It/lib t/TestsFor/Person.pm! t/TestsFor/Person.pm .. # ! # TestsFor::Person->constructor! 1..7! ok 1 - Person->can('new’)! ok 2 - ... and the constructor should succeed! ok 3 - ... and the object it returns isa Person! # ! # TestsFor::Person->full_name! ok 4 - first_name correct! ok 5 - last_name correct! ok 6 - Person->can('full_name')! ok 7 - ... and it should return the correct fullname! ok! All tests successful.! Files=1, Tests=7, 0 wallclock secs! Result: PASS! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 24. package Person::Employee; use Moose;! extends 'Person';! has ‘employee_number’ => ( ! is => ‘ro’, ! isa => ‘Int’,! );! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 25. package TestsFor::Person::Employee;! use Test::Class::Most parent => 'TestsFor::Person';! sub employee_number : Tests(2) { my $test = shift;! my $employee = $test->class->new(! first_name => 'John',! last_name => 'Public',! employee_number => 17,! );! can_ok $employee, 'employee_number’;! is $employee->employee_number, 17, ! '... the employee number is correct';! }! 1;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 26. t/TestsFor/Person/Employee.pm .. # ! # ! # TestsFor::Person::Employee->constructor! # TestsFor::Person->constructor! ok 10 - Person->can('new')! 1..16! ok 11 - ... and the constructor should ok 1 - Person::Employee->can('new')! succeed! ok 2 - ... and the constructor should succeed! ok 12 - ... and the object it returns isa ok 3 - ... and the object it returns isa Person! Person::Employee! # ! # ! # TestsFor::Person->full_name! # TestsFor::Person::Employee->employee_number! ok 13 - first_name correct! ok 4 - Person::Employee- ok 14 - last_name correct! >can('employee_number')! ok 15 - Person->can('full_name')! ok 5 - ... the employee number is correct! ok 16 - ... and it should return the correct # ! fullname! # TestsFor::Person::Employee->full_name! ok! ok 6 - first_name correct! All tests successful.! ok 7 - last_name correct! Files=1, Tests=16, 0 wallclock secs! ok 8 - Person::Employee->can('full_name')! Result: PASS! ok 9 - ... and it should return the correct fullname! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 27. t/TestsFor/Person/Employee.pm .. # ! # ! # TestsFor::Person::Employee->constructor! # TestsFor::Person->constructor! ok 10 - Person->can('new')! 1..16! ok 11 - ... and the constructor should ok 1 - Person::Employee->can('new')! succeed! ok 2 - ... and the constructor should succeed! ok 12 - ... and the object it returns isa ok 3 - ... and the object it returns isa Person! Person::Employee! # ! # ! # TestsFor::Person->full_name! # TestsFor::Person::Employee->employee_number! ok 13 - first_name correct! ok 4 - Person::Employee- ok 14 - last_name correct! >can('employee_number')! ok 15 - Person->can('full_name')! ok 5 - ... the employee number is correct! ok 16 - ... and it should return the correct # ! fullname! # TestsFor::Person::Employee->full_name! ok! ok 6 - first_name correct! All tests successful.! ok 7 - last_name correct! Files=1, Tests=16, 0 wallclock secs! ok 8 - Person::Employee->can('full_name')! Result: PASS! ok 9 - ... and it should return the correct fullname! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 28. t/TestsFor/Person/Employee.pm .. # ! # ! # TestsFor::Person::Employee->constructor! # TestsFor::Person->constructor! ok 10 - Person->can('new')! 1..16! ok 11 - ... and the constructor should ok 1 - Person::Employee->can('new')! succeed! ok 2 - ... and the constructor should succeed! ok 12 - ... and the object it returns isa ok 3 - ... and the object it returns isa Person! Person::Employee! # ! # ! # TestsFor::Person->full_name! # TestsFor::Person::Employee->employee_number! ok 13 - first_name correct! ok 4 - Person::Employee- ok 14 - last_name correct! >can('employee_number')! ok 15 - Person->can('full_name')! ok 5 - ... the employee number is correct! ok 16 - ... and it should return the correct # ! fullname! # TestsFor::Person::Employee->full_name! ok! ok 6 - first_name correct! All tests successful.! ok 7 - last_name correct! Files=1, Tests=16, 0 wallclock secs! ok 8 - Person::Employee->can('full_name')! Result: PASS! ok 9 - ... and it should return the correct fullname! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 29. t/TestsFor/Person/Employee.pm .. # ! # ! # TestsFor::Person::Employee->constructor! # TestsFor::Person->constructor! ok 10 - Person->can('new')! 1..16! ok 11 - ... and the constructor should ok 1 - Person::Employee->can('new')! succeed! ok 2 - ... and the constructor should succeed! ok 12 - ... and the object it returns isa ok 3 - ... and the object it returns isa Person! Person::Employee! # ! # ! # TestsFor::Person->full_name! # TestsFor::Person::Employee->employee_number! ok 13 - first_name correct! ok 4 - Person::Employee- ok 14 - last_name correct! >can('employee_number')! ok 15 - Person->can('full_name')! ok 5 - ... the employee number is correct! ok 16 - ... and it should return the correct # ! fullname! # TestsFor::Person::Employee->full_name! ok! ok 6 - first_name correct! All tests successful.! ok 7 - last_name correct! Files=1, Tests=16, 0 wallclock secs! ok 8 - Person::Employee->can('full_name')! Result: PASS! ok 9 - ... and it should return the correct fullname! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 30. t/TestsFor/Person/Employee.pm .. # ! # ! # TestsFor::Person::Employee->constructor! # TestsFor::Person->constructor! ok 10 - Person->can('new')! 1..16! ok 11 - ... and the constructor should ok 1 - Person::Employee->can('new')! succeed! ok 2 - ... and the constructor should succeed! ok 12 - ... and the object it returns isa ok 3 - ... and the object it returns isa Person! Person::Employee! # ! # ! # TestsFor::Person->full_name! # TestsFor::Person::Employee->employee_number! ok 13 - first_name correct! ok 4 - Person::Employee- ok 14 - last_name correct! >can('employee_number')! ok 15 - Person->can('full_name')! ok 5 - ... the employee number is correct! ok 16 - ... and it should return the correct # ! fullname! # TestsFor::Person::Employee->full_name! ok! ok 6 - first_name correct! All tests successful.! ok 7 - last_name correct! Files=1, Tests=16, 0 wallclock secs! ok 8 - Person::Employee->can('full_name')! Result: PASS! ok 9 - ... and it should return the correct fullname! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 31. sub startup : Tests(startup) {! my $test = shift;! return if $test->class;! my $class = ref $test;! $class =~ s/^TestsFor:://;! eval "use $class";! die $@ if $@;! $test->class($class);! }! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 32.   TestsFor::Person::Employee inherits TestsFor::Person’s tests   We don’t hard-code the class name   Inherited test methods rock! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 33. Attribute Name Phase Tests(startup)! When the test class starts Tests(setup)! Before each test method Tests(teardown)! After each test method Tests(shutdown)! When the test class finishes http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 34.   Connect to a database (often in startup)   Set up fixtures/transactions (setup)   Clean fixtures/rollbacks (teardown)   Disconnect from database (shutdown)   (They’re a better place for object construction) http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 35. package TestsFor::Customer;! package TestsFor::Person::Employee;! use Test::Class::Most! use Test::Class::Most! parent => ‘My::Test::Class’,! parent => ‘TestsFor::Customer’,! attributes => [‘dbh’];! attributes => [‘employee’];! sub aaa_connect_to_db : Tests(setup) {! sub bbb_employee : Tests(setup) {! my $test = shift;! my $test = shift;! my $dbh = DBI->connect(…);! my $employee = $test->dbh->…;! # or $test->{dbh} = $dbh;! $test->employee($employee);! $test->dbh($dbh);! }! }! sub kill_employee : Tests {! sub some_test : Tests {! my $test = shift;! my $test = shift;! my $employee = $test->employee;! my $dbh = $test->dbh;! can_ok( $employee, ‘suffocate’ );! …! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 36. package TestsFor::Customer;! package TestsFor::Person::Employee;! use Test::Class::Most! use Test::Class::Most! parent => ‘My::Test::Class’,! parent => ‘TestsFor::Customer’,! attributes => [‘dbh’];! attributes => [‘employee’];! sub aaa_connect_to_db : Tests(setup) {! sub bbb_employee : Tests(setup) {! my $test = shift;! my $test = shift;! my $dbh = DBI->connect(…);! my $employee = $test->dbh->…;! # or $test->{dbh} = $dbh;! $test->employee($employee);! $test->dbh($dbh);! }! }! sub kill_employee : Tests {! sub some_test : Tests {! my $test = shift;! my $test = shift;! my $employee = $test->employee;! my $dbh = $test->dbh;! can_ok( $employee, ‘suffocate’ );! …! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 37. package TestsFor::Customer;! package TestsFor::Person::Employee;! use Test::Class::Most! use Test::Class::Most! parent => ‘My::Test::Class’,! parent => ‘TestsFor::Customer’,! attributes => [‘dbh’];! attributes => [‘employee’];! sub setup : Tests(setup) {! sub setup : Tests(setup) {! my $test = shift;! my $test = shift;! my $dbh = DBI->connect(…);! $test->SUPER::setup;! # or $test->{dbh} = $dbh;! my $employee = $test->dbh->…;! $test->dbh($dbh);! $test->employee($employee);! }! }! sub some_test : Tests {! sub kill_employee : Tests {! my $test = shift;! my $test = shift;! my $dbh = $test->dbh;! my $employee = $test->employee;! …! can_ok( $employee, ‘suffocate’ );! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 38. Before Tests After Tests sub startup:Test(startup) {! sub teardown:Test(teardown){! my $test = shift;! my $test = shift;! $test->SUPER::startup;! # finish your teardown! # finish your startup! $test->SUPER::teardown;! }! }! sub setup : Test(setup) {! sub shutdown:Test(shutdown){! my $test = shift;! my $test = shift;! $test->SUPER::setup;! # finish your shutdown! # finish your setup! $test->SUPER::shutdown;! }! }! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 39. # t/test_class_tests.t! # Don’t Do This!! use lib ‘t/lib’;! use TestsFor::Person;! use TestsFor::Person::Employee;! Test::Class->runtests;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 40. # Don’t Do This because you’ll forget one!! use lib ‘t/lib’;! use TestsFor::Person;! use TestsFor::Person::Employee;! use TestsFor::Database;! use TestsFor::PurchaseOrder;! use TestsFor::Alibi;! use TestsFor::Embezzlement;! use TestsFor::PaddingMySlides;! Test::Class->runtests;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 41. # Do This!! use Test::Class::Load ‘t/lib’;! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 42.   Finds your test classes for you   My example relies on INIT { Test::Class->runtests } in My::Test::Class.   Run the test suite: prove -l t/test_class_tests.t!   Or a single test class: prove -lv -It/lib t/TestsFor/Person.pm http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 43.   Name test classes after their classes (if possible)   Name test methods after their methods (if possible)   … you can’t name a method new()!   Create your own base test class   … with stub test control methods   Name test control methods after their attribute   Don’t put tests in your test control methods   Do not hardcode the name of the class to test! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 44.   Part 1: Getting started with Test::Class   Part 2: Inheriting Test::Class tests   Part 3: Making your testing life easier   Part 4: Using test control methods   Part 5: Test::Class Tricks http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass
  • 45.   Beginning Perl, Wrox Press   Introduction to Perl   CPAN   Modules   Objects (Moose!)   Testing   PSGI+Plack   DBIx::Class   Catalyst   And more! http://www.slideshare.net/Ovid/a-whirlwind-tour-of-testclass

Hinweis der Redaktion

  1. Single versus multiple processesTests that don’t map to classesDetailed testing strategiesWhy some of this presentation works