SlideShare a Scribd company logo
Getting Testy With Perl
Steven Lembark
Workhorse Computing
lembark@wrkhors.com
Cultured Perl
Perl's “test culture” is part of the language.
Test::* modules easily added to Perl code.
Smoke testing provided as part of CPAN.
Reporter accumulates results from installers.
Language structure, modules work together.
Where there's smoke, there's Perl.
CPAN::Reporter send back success/fail.
CPAN testers: variety of platforms, daily reports.
cpan-testers & cpan-testers-discuss mailing lists.
http://cpantesters.org/
Community effort at testing is unique to Perl.
Excellent Reference
Perl Testing: A developer's Notebook,
O'Reilly Press
Wonderful example of a good howto-book.
Includes modules, ways to use them with variations.
Good cover-to-cover read.
Perl is easy to test
Test::* modules do most of the work.
Use the wheels, don't re-invent:
Test::Simple, Test::More, Test::Deep,
Test::Builder, Test::Coverage, Object::Exercise
Perl adds introspection.
One­stop shopping
Perl as a great glue language.
Use perl to test other programs.
Have other programs output TAP.
Combined with “inline” you can test almost anything!
Test your tests!
Devel::Coverage have you tested all of the code?
Test::Builder roll your own tests.
Build you own re-usable test components:
Test::Harness::Straps
Test::Builder::Tester
“Test” code can do more
Pre-load fixed data into a database.
Validate the working environment.
Execute daily cleanups in cron.
Testing simply 
Count hardwired:
use Test::Simple tests => 6;
Difference in count will be an error.
Its all “ok”
use Test::Simple tests => 2;
# ok( boolean, message );
ok 1 == 1, “Count: '1' (1)”;
ok 2 == 1, “Count: '2' (1)”;
Output like:
ok 1 ­ Count: '1' (1)
not ok 2 ­ Count: '2' (1)
Its all “ok”
use Test::Simple tests => 2;
# ok( boolean, message );
ok 1, 'It passed!';
Output like:
1..2
ok 1 ­ It passed!
# Looks like you planned 2 tests but ran 1.
Seen these before?
“not ok 10 ­ Count”
“not ok 11 ­ Format”
“not ok 5 ­ File or directory not found.”
OK, now what?
Designing tests:
Test what matters.
Report something useful.
Isolate the failure
What to fix:
ok -e $path , “Existing: '$path'”;
ok -d _ , “Directory: '$path'”;
ok -r _ , “Readable: '$path'”;
ok -w _ , “Writeable '$path'”;
Q: Why all of the quotes?
ok -e $path, “Existing dir: $path”
Q: Why all of the quotes?
ok -e $path, “Existing dir: $path”
not ok 1 - Existing dir: /var/tmp
not ok 1 Existing dir: /var/tmp
Q: Why all of the quotes?
ok -e $path, “Existing dir: '$path'”
not ok 1 - Existing dir: '/var/tmp '
not ok 1 Existing dir: '/var/tmp
'
Good general format
Include what you found, what you expect.
You'll need them both with “not ok”:
ok $got eq $want, 'Name: '$got' ($want)”;
not ok 99 – Name: '' (Jow Bloe)
not ok 99 – Name: '1 Main St.' (Jow Bloe)
not ok 99 – Name: 'Jow Bloe' ()
not ok 99 – Name: 'Jow Bloe' (User::Name=0x1A...
Test::Simple may be enough
Generate a plan.
“ok” generates TAP output.
Test count is fixed.
This works for many day-to-day tests.
But Wait! There's More!
Test::More
plan, done_testing test counts
is, isnt, like, unlike stringy “ok”
pass, fail skip the boolean
use_ok, require_ok module test
note, diag, explain messages
Flexable count
Set count with “plan”.
Compute from test input:
plan tests => 42;
plan tests => 3 * keys $config;
plan tests => 2 * values $query_output;
Test count varys?
Skip plan.
When you're done testing
Just say so:
done_testing;
Generates final report.
Plan count is checked here.
No plan, no count check.
Notes show up with “prove ­v”
note “read_config from '$config_path'”;
my $path = read_config 'tmp_dir';
ok -e $path, “Exists: '$path' (tmp_dir)”;
$ prove ­v;
# read_config from './etc/pass1.conf'
not ok 1 – Exists: '/var/tmp/foobar ' (tmp_dir)
Diagnostics show why tests failed
Show up without “-v”.
ok … or diag “Oopsie...”;
ok grep /blah/, @test_input, 'Found blah'
or diag “Missing 'blah':”, @test_input;
ok $dbh, “Connected”
or diag “Failed connect: '$dsn'”;
Explain shows exactly what failed
“explain” shows nested structure.
Use with “note” to show setup details.
With “diag” shows extra info on failure.
my $dbh = DBI->connect( @argz );
ok $dbh, 'Database connected'
or diag 'Connect args:', explain @argz;
Stringy “ok”
like, not_like use regexen.
saves “=~” syntax in the tests:
like $stuff, qr/milk/, “Got: 'milk'?”
or diag “Have: '$stuff' instead”;
not ok 1 ­ Got: 'milk'?
# Have 'very new cheese' instead
Variable number of tests
If-logic generates variable number of tests.
Skip “plan”, use “done_testing”.
Taking it pass/fail
if( $obj = eval { $class->constructify } )
{
# validate object contents
}
else
{
# nothing more to test
fail “Failed constructify: $@”;
}
Test expected errors
eval
{
$obj->new( $junk );
fail "No exception: foo( $junk )?";
1
}
or do
{
# validate error handling
...
}
Controlling test cycle
Abort if everything will fail.
Avoid expensive, specialized, un-necesary tests.
Saves extraneous code in all of the tests.
BAIL_OUT: Knowing when to give up
Aborts all testing.
Unsafe or guaranteed failure.
Useful in early test for environment, arg checks.
BAIL_OUT
BAIL_OUT 'Do not run tests as su!' unless $>;
BAIL_OUT 'Missing $DB' unless $ENV{DB};
-e $test_dir or mkdir $dir, 0777
or BAIL_OUT “Failed mkdir: '$dir', $!”;
-d $test_dir or BAIL_OUT “Missing: '$dir'”;
-r _ or BAIL_OUT “Un-readable: '$dir'”;
-w _ or BAIL_OUT “Un-writeable: '$dir'”;
“SKIP” blocks
Skip a block with test count and message.
Adjust the plan test count.
Expensive or specialized tests.
Skip external tests
SKIP:
{
skip “No database (TEST_DB)”, 8 if ! $ENV{ TEST_DB };
# or … no network available...
# or … no server handle...
...
}
Skip expensive tests
SKIP:
{
skip “Used for internal development only”, 12
unless $ENV{ EXPENSIVE_TESTS };
# test plan count reduced by 12
...
}
Skip dangerous tests
SKIP:
{
skip “Unsafe as superuser”, 22 unless $>;
# at this point the tests are not running su.
...
}
You'll usually use Test::More
note & diag nearly always worth using.
plan & done_testing makes life easier.
Still have “ok” for the majority of work.
Testing Structures
“like” syntax with nested structure:
use Test::Deep;
cmp_deeply $found, $expect, $message;
Great for testing parser or grammar outcome.
Devel::Cover: what didn't you check?
All of the else blocks?
All of the “||=” assignments?
All of the “... or die ...” branches?
Devel::Cover bookkeeps running code.
Reports what you didn't test.
Tells you what test to write next.
Similar to NYTProf:
Run your program & summarize the results:
$ cover -test;
or
$ perl -MDevel::Cover ./t/foo.t;
$ cover;
Running “cover” generates the report.
Introspection simplifies testing
Want to test database connect failure.
Can't assume SQL::Lite.
Flat file databases are messy.
Guarantee that something fails?
You could write an operation that should fail.
Then again, it might not...
Making sure you fail
Override class methods.
Override Perl functions.
Result:
Mock objects,
Mock methods,
Mock perl.
Mock Objects
Test your wrapper handling failure?
Override DBI::connect with sub { die … }.
No guess: You know it's going to fail.
Mock Modules
Your test:
*DBI::connect = sub { die '…' };
my $status = eval { $obj->make_connection };
my $err = $@;
# test $status, $err, $obj...
Force an exception 
use Symbol qw( qualify_to_ref );
# e.g., force_exception 'Invalid username', 'connect', 'DBI';
# ( name, packcage ) or ( “package::name” )
sub force_exception
{
chomp( my $messsage = shift );
my $ref = qualify_to_ref @_;
undef &{ *$ref };
*{ $ref } = sub { die “$messagen” };
return
}
Testing multiple failures
for( @testz )
{
my( $msg, $expect ) = @$_;
force_exception $msg, 'DBI::connect';
my $status = eval { $wrapper->connect };
my $err = $@;
# your tests here
}
Avoid caller cleanup
Override with “local”
sub force_exception
{
my ( $proto, $method, $pkg, $name, $msg ) = splice @_, 0, 5;
my $ref = qualify_to_ref $name, $pkg;
local *{ $ref } = sub { die “$msg” };
# exit from block cleans up local override.
# caller checks return, $@, $proto.
eval { $proto->$method( @_ ) }
}
Mock Perl
Override perl: *Core::Global::<name>
Is “exit” is called?
my $exits = 0;
*Core::Global::exit = sub { $exits = 1 };
eval { frobnicate $arg };
ok $exits, “Frobnicate exits ($exits)”;
Devel::Cover & Mocking
The biggest reason for mock anything:
Force an outcome to test a branch.
Iterate:
Test with Devel::Cover.
See what still needs testing.
Mock object/method/function forces the branch.
Automated testing
Lazyness is a virtue.
Avoid cut+paste.
Let Perl do the work!
Example: Sanity check modules
Use symlinks.
Validate modules compile.
Check package argument.
require_ok $package; # ok if require-able.
use_ok $package; # ok if use-able.
Make the links
Path below ./lib.
Replace slashes with dashes.
Add a leading “01”.
Symlink them all to a generic baseline test.
Symlinks look like:
01­Wcurve­Util.t   generic­01­t→
use FindBin::libs;
use Test::More;
use File::Basename qw( basename );
my $madness = basename $0, '.t'; # 01-WCurve-Util
$madness =~ s{^ 01-}{}x; # WCurve-Util
$madness =~ s{ W+ }{::}gx; # WCUrve::Util
if( use_ok $madness )
{
# check for correct package argument.
ok $madness->can( 'VERSION' ), “$maddness has a method”;
ok $a = $madness->VERSION, “$madness is '$a'”;
}
done_testing;
./t/generic­01­t
./t/make­generic­links
#!/bin/bash
cd $(dirname $0);
rm 01-*.t;
find ../lib/ -name '*.pm' |
perl -n 
-e 'chomp;' 
-e 's{^ .+ /lib/}{}x' 
-e 's{.pm $}{.t}x' 
-e 'tr{/}{-} 
-e 'symlink “01-generic-t” => “01-$_”';
exit 0;
Similar checks for config files
Add “00-” tests to reads config files.
Combine “ok” with Config::Any.
Now make-generic-links tests config & code.
“prove” runs them all in one pass.
The Validation Two­Step
Use with git for sanity check:
git pull &&
./t/make-generic-links &&
prove --jobs=2 –-state=save &&
git tag -a “prove/$date” &&
git push &&
git push –-tag ;
Exercise for healthy objects
Data-driven testing for a single object.
Data includes method, data, expected return.
Module iterates the tests, reports results.
When tests or expected values are generated.
use Object::Exercise;
my @testz =
(
[
[ qw( name ) ], # method + args
[ q{Jow Bloe} ], # expected return
],
[
[ qw( street ) ],
[ q{1 Nuwere St} ],
],
[
[ qw( street number ) ], # $obj->address( 'number' )
[ qw( 1 ) ],
'Check street number' # hardwired message
],
);
Person->new( 'Jow Blow' => '1 Nuwere St' )->$exercise( @testz );
Load fixed data
Flat file -> arrayrefs
“insert” as method, [1] as return.
Load the data with:
$sth->$exercise( @data )
Get “ok” message for each of the data record.
Roll your own: Test::Builder
Mirrors Test::More with a singleton object.
my $test = Test::Builder->new;
$test->ok( $boolean, $success_message )
or $test->diag( $more_info );
Spread single test across multiple modules.
Testing Testing
Test::Build::Tester wraps your tests.
Forces test to return not-ok in order to test it.
Ignores the output of the test being tested.
Validate the test plan.
Getting the most out of prove
Save state: re-run failed tests:
$prove –state=save;
# fix something...
$prove –state=save,failed;
Parallel execution with “--jobs”.
“perldoc” is your friend!
Great, but my shop uses <pick one>
Test multiple languages with Inline.
Include C, C++, Python...
Multiple Perl versions.
Mix languages to test interfaces.
One­stop teting for your API lib's
Need to test multi-language support?
Use Perl to move data between them.
Unit-test C talking to Java.
Example: Testing your C code
use Inline C;
use Test::Simple tests => 1;
my $a = 12 + 34;
my $b = add( 12, 34 );
ok $a == $b, "Add: '$b' ($a)";
__END__
__C__
int add(int x, int y)
{
return x + y;
}
Example: Testing your C code
$ prove ­v add.t
add.t ..
1..1
ok 1 ­ Add: '46' (46)
ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs
( 0.05 usr  0.00 sys +  0.09 cusr  0.00 csys = ... 
Result: PASS
Example: Testing your C code
You can call into a library.
Write a whole program.
Inline builds the interface.
Test Anything Protcol
Inline Language Support Modules add languages.
Inline supports:
C, C++, Java, Python, Ruby, Tcl,
Assembler, Basic, Guile, Befunge, Octave,
Awk, BC, TT (Template Toolkit), WebChat,
and (of course) Perl.
Really: Any Thing
Say you had a quad-rotor UAV...
You'd write a Perl API for it, wouldn't you?
UAV::Pilot::ARDrone, for example.
But then you'd have to test it...
First: Define the test actions
my @actionz =
(
[
takeoff => 10
],
[
wave => 8000
],
[
flip_left => 5000
],
[
land => 5000,
send => $expect
],
);
plan tests => 2 + @actionz;
Basic set of actions:
Takeoff, wobble, flip,
and land.
Final “send” validates
end-of-channel.
Control interfaces
BAIL_OUT
avoids running
without controls.
my $driver
= UAV::Pilot::ARDrone::Driver->new
(
{
host => $HOST,
}
)
or BAIL_OUT "Failed construct";
eval
{
$driver->connect;
pass "Connected to '$HOST'";
}
or BAIL_OUT "Failed connect: $@";
Error handler for actions
Attempt the last
action (land) on
errors.
sub oops
{
eval { execute $actionz[ -1 ] }
or
BAIL_OUT "Literal crash expected";
}
sub execute
{
state $a = $event;
my ( $ctrl_op, $time, $cv_op, $cv_val ) = @$_;
$a = $a->add_timer
(
{
duration => $time,
duration_units => $event->UNITS_MILLISECOND,
cb =>
sub
{
$control->$ctrl_op or die "Failed: $ctrl_op";
$cv->$cv_op( $cv_val ) if $cv_op;
pass "Execute: '$ctrl_op' ($cv_op)";
}
}
)
Execute the actions
“note” here
describes what
to expect.
for( @actionz )
{
note "Prepare:n", explain $_;
eval { execute $_ }
or
oops;
}
$event->init_event_loop;
Check the end­of­channel 
my $found = $cv->recv;
if( $found eq $expect )
{
pass "Recv completed '$found' ($expect)";
}
else
{
fail "Recv incomplete ($found), send emergency land";
oops;
}
done_testing;
Execute the tests
$ perl t/01-test-flight.t
1..6
# Connect to: '192.168.1.1'
(UAV::Pilot::ARDrone::Driver)
ok 1 - Connected to '192.168.1.1'
# U::P::EasyEvent has a socket
# Prepare:
# [
# 'takeoff',
# 10
# ]
# Prepare:
# [
# 'wave'
“pass” shows what happens
# Prepare:
# [
# 'land',
# 5000,
# 'send',
# '123'
# ]
ok 2 - Execute: 'takeoff' ()
“pass” shows what happens
# Prepare:
# [
# 'land',
# 5000,
# 'send',
# '123'
# ]
ok 2 - Execute: 'takeoff' ()
ok 3 - Execute: 'wave' ()
“pass” shows what happens
# Prepare:
# [
# 'land',
# 5000,
# 'send',
# '123'
# ]
ok 2 - Execute: 'takeoff' ()
ok 3 - Execute: 'wave' ()
ok 4 - Execute: 'flip_left' ()
“pass” shows what happens
# Prepare:
# [
# 'land',
# 5000,
# 'send',
# '123'
# ]
ok 2 - Execute: 'takeoff' ()
ok 3 - Execute: 'wave' ()
ok 4 - Execute: 'flip_left' ()
ok 5 - Execute: 'land' (send)
“pass” shows what happens
# Prepare:
# [
# 'land',
# 5000,
# 'send',
# '123'
# ]
ok 2 - Execute: 'takeoff' ()
ok 3 - Execute: 'wave' ()
ok 4 - Execute: 'flip_left' ()
ok 5 - Execute: 'land' (send)
ok 6 - Recv completed '123' (123)
Cultured Perls
The Developer's Notebook is a great resource.
POD for Test::More == wheels you don't re-invent.
POD for prove == make life faster, easier.
cpantesters.org: test results for modules by platform.
Stay cultured, be testy: use perl.

More Related Content

What's hot

BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
Workhorse Computing
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
Workhorse Computing
 
Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
Workhorse Computing
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
Workhorse Computing
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
Workhorse Computing
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
Workhorse Computing
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
Workhorse Computing
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and BenchmarksLies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
Workhorse Computing
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
Workhorse Computing
 
Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2nottings
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Puppet
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to do
Puppet
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
ExoLeaders.com
 
Unit Testing in SilverStripe
Unit Testing in SilverStripeUnit Testing in SilverStripe
Unit Testing in SilverStripe
Ingo Schommer
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
Brian Gesiak
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
Perl Careers
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
Roy Yu
 
Modern Perl
Modern PerlModern Perl
Modern Perl
Dave Cross
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
Mark Baker
 

What's hot (20)

BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and BenchmarksLies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2Puppet camp chicago-automated_testing2
Puppet camp chicago-automated_testing2
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
 
Puppet: What _not_ to do
Puppet: What _not_ to doPuppet: What _not_ to do
Puppet: What _not_ to do
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Unit Testing in SilverStripe
Unit Testing in SilverStripeUnit Testing in SilverStripe
Unit Testing in SilverStripe
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
 

Similar to Getting testy with Perl

Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
Kent Cowgill
 
Testing With Test::Class
Testing With Test::ClassTesting With Test::Class
Testing With Test::Class
Curtis Poe
 
The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's Toolkit
Stephen Scaffidi
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
noelrap
 
Ansible testing
Ansible   testingAnsible   testing
Ansible testing
Scott van Kalken
 
Test tutorial
Test tutorialTest tutorial
Test tutorialmsksaba
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionCool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Schalk Cronjé
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
Perl Testing
Perl TestingPerl Testing
Perl Testing
lichtkind
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
Ahmed Yahia
 
Software Testing
Software TestingSoftware Testing
Software Testing
Lambert Lum
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
Schalk Cronjé
 
Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)
Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)
Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)
Alex Balhatchet
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
Cory Foy
 
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
Rodolfo Carvalho
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
Dror Helper
 

Similar to Getting testy with Perl (20)

Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Testing With Test::Class
Testing With Test::ClassTesting With Test::Class
Testing With Test::Class
 
IntroTestMore
IntroTestMoreIntroTestMore
IntroTestMore
 
IntroTestMore
IntroTestMoreIntroTestMore
IntroTestMore
 
The Essential Perl Hacker's Toolkit
The Essential Perl Hacker's ToolkitThe Essential Perl Hacker's Toolkit
The Essential Perl Hacker's Toolkit
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Ansible testing
Ansible   testingAnsible   testing
Ansible testing
 
Test-Tutorial
Test-TutorialTest-Tutorial
Test-Tutorial
 
Test-Tutorial
Test-TutorialTest-Tutorial
Test-Tutorial
 
Test tutorial
Test tutorialTest tutorial
Test tutorial
 
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers VersionCool Jvm Tools to Help you Test - Aylesbury Testers Version
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
Perl Testing
Perl TestingPerl Testing
Perl Testing
 
Testing in Laravel
Testing in LaravelTesting in Laravel
Testing in Laravel
 
Software Testing
Software TestingSoftware Testing
Software Testing
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
 
Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)
Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)
Introduction to Writing Readable and Maintainable Perl (YAPC::EU 2011 Version)
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
O CPAN tem as ferramentas que você precisa para fazer TDD em Perl, o Coding D...
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 

More from Workhorse Computing

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
Workhorse Computing
 
mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
Workhorse Computing
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
Workhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
Workhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
Workhorse Computing
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
Workhorse Computing
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Workhorse Computing
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
Workhorse Computing
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
Workhorse Computing
 
Paranormal stats
Paranormal statsParanormal stats
Paranormal stats
Workhorse Computing
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.
Workhorse Computing
 
Putting some "logic" in LVM.
Putting some "logic" in LVM.Putting some "logic" in LVM.
Putting some "logic" in LVM.
Workhorse Computing
 
Selenium sandwich-2
Selenium sandwich-2Selenium sandwich-2
Selenium sandwich-2
Workhorse Computing
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium
Workhorse Computing
 
Docker perl build
Docker perl buildDocker perl build
Docker perl build
Workhorse Computing
 
Designing net-aws-glacier
Designing net-aws-glacierDesigning net-aws-glacier
Designing net-aws-glacier
Workhorse Computing
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
Workhorse Computing
 

More from Workhorse Computing (17)

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
 
Paranormal stats
Paranormal statsParanormal stats
Paranormal stats
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.
 
Putting some "logic" in LVM.
Putting some "logic" in LVM.Putting some "logic" in LVM.
Putting some "logic" in LVM.
 
Selenium sandwich-2
Selenium sandwich-2Selenium sandwich-2
Selenium sandwich-2
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium
 
Docker perl build
Docker perl buildDocker perl build
Docker perl build
 
Designing net-aws-glacier
Designing net-aws-glacierDesigning net-aws-glacier
Designing net-aws-glacier
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
 

Recently uploaded

The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 

Recently uploaded (20)

The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 

Getting testy with Perl