SlideShare uma empresa Scribd logo
1 de 69
Baixar para ler offline
A Perl Testing Tutorial



       chromatic
Why to Test
ensure the code does what it should do
q   no missing functionality
q   no accidental functionality
q   when your tests all pass, you're done
explore boundary conditions
q   how does the code handle bad input?
q   how does the code handle very bad input?
prevent (known) regressions
q   no tested features can be broken accidentally
q   no fixed bugs can reoccur
improve bug reports
q   test output can pinpoint errors
q   easily generated by end users
run this and send me the output
enable refactoring
q   you break it, you know it right away
q   side effects immediately evident
q   well-tested code tends to be more modular
    x   I had several pre-existing modules with similar behavior to test.
        They were only tangentially related. After the second test suite
        turned out almost the same, I realized I needed a parent class. I
        moved most of the tests to the parent class and the inherited
        classes ended up much simpler and very much shorter. Their tests
        were much simpler, too. This gave me less code to maintain, fewer
        tests to write, and more flexibility for adding new features.
improve API
q   hard to test code may be hard to use
q   writing a test first forces you to use the interface before you
    create it
    x   simpler interfaces are easier to test
    x   smaller functions are easier to reuse
promote automation
x   easy to test code is usually well-decoupled
x   easy to test code is, by definition, scriptable
ease maintainability
q   tests are a safety net
    x   if you don't understand this by now, I'll repeat it once again
q   well-written tests serve as a sort of documentation
    x   demonstrate what features the software should have
    x   demonstrate what behavior the code should express
Don't be Scared!
Don't be Scared!
q   writing good tests exercises the same muscles as writing good
    code
q   if you can write code, you can write tests
q   if you can write good code, you can be taught to write good
    tests
Testing Has Psychological Benefits
q   writing tests (especially test first) makes it easier to write tests
q   well-tested code is more fun to hack
q   test-first programming gives instant feedback
q   that's instant positive feedback, most of the time
Perl makes it easy
q   ExtUtils::MakeMaker and the 'test' target
q   Test::* modules hide the Test::Harness expectations
q   if lazy dopes like us can do it, you can too!
Basic Tests
Thinking "ok"
print "ok";
print "not ok";

q   basis for all tests
q   a simple boolean condition
q   generally numbered sequentially
More thinking "ok"
q   why printing is a loss:
    x   same arguments as using subroutines (duplicate code)
    x   manual test renumbering
    x   no diagnostics unless you provide them
        Ë   what matched
        Ë   what didn't match
        Ë   which test failed and where
    x   no built-in provision for more complex constructs
    x   can be hard to maintain
The ok() function
ok( 1 == 1 );
q   basis for all Test::Simple, Test::More, Test::Builder tests
q   a simple boolean condition
q   why it's a win:
    x   alleviates duplicate code
    x   associates a name with a test
    x   expresses test intent more clearly
    x   avoids portability concerns
Test::Simple and its API
planning tests
q   helps catch too many/not enough test errors
q   helps identify which test fails
q   required by Test::Harness

use Test::Simple tests => 10;
use Test::Simple 'no_plan';
tests => n
q   produces 1..n output for Test::Harness
q   should be set when the test suite is complete
no_plan
q   produces 1..actual output at the end of the test
q   when you don't know how many tests will run
q   very handy while developing a module
q   not so handy when distributing a module
ok()
q   scalar context of operands
q   first argument always true or false
q   second argument optional, test name
q   condition is code expression of the test name
q   test name is a declaration of the intent of the condition
ok() passing
ok( 1, '1 should be true' );

ok 1 - 1 should be true
ok() failing
ok( 0, '0 should be true' );

not ok 2 - 0 should be true
#     Failed test (demotest.pl at line 17)
success is not a gray area (individual tests)
  q   pass, or fail, there is no maybe
  q   test the smallest piece possible
  q   test one thing at a time
  q   pass quietly
      x   avoid errors
      x   avoid warnings
      x   test for errors and warnings if you must
success is all or nothing (test suite)
q   stamp out expected failures
    x   undermine confidence in the code
    x   clutter up screens and logs
    x   hide new problems
q   keeping changes small helps localize damage
q   keeping tests working helps localize damage
q   there are ways to isolate platform-specific tests
Integrating testing with the development process
catching regressions
q   most bugs aren't new, they happen again and again
q   why let them reoccur?
q   write a test for every new bug
testing first
q   teeny, tiny, mini-iterations
q   break each task into boolean expressions
q   "What feature do I need next?"
    x   smallest element of overall task
    x   one small step at a time
The two test-first questions
q   "How can I prove that this feature works?"
    x   the simplest test that will fail unless the feature works
    x   THE TEST MUST FAIL
q   "What is the least amount of code I can write to pass the test?"
    x   the simpler the test, the simpler the code you need
    x   THE TEST MUST NOW PASS
q   this produces known good code and a comprehensive test
    suite
q   be sure to run the entire test suite after you implement a task
writing testable code
q   the smaller the unit, the better
q   the simpler the unit, the better
q   the better the test suite, the easier it is to refactor
q   writing your tests first promotes this!
distributing tests
q   Test.pm is easier to distribute
    x   single module, does not depend on Test::Builder
    x   compatible with Test::More API
q   Test::Simple suite can be bundled with module
    x   CGI.pm does this, among others
q   Test::Simple ships with 5.8
q   a module can depend on Test::Simple
Exploring the Test::More API
graduating from Test::Simple to Test::More, or why
                ok() is not enough
     q   one bit of data -- either it passed or it failed
     q   contains little debugging information
         x   what did you get?
         x   what did you receive?
         x   do you really want to exchange "add a print at line 43" emails?
     q   true laziness is a sign of good testing
matching things - is()
q   asks the question "are these two things equal?"
q   does a pretty good job of guessing at the type of equality
q   takes an optional test name, so use one
q   special cased for 'undef'
is() passing
is( 2 + 2, 4, 'Two plus two should be four' );

ok 1 - Two plus two should be four
is() failing
is( 2 + 2, 5, 'Two plus two should be five' );

not ok 2 - Two plus two should be five
#     Failed test (demotest.pl at line 8)
#          got: '4'
#     expected: '5'
matching things - isnt()
q   asks the question "are these two things not equal?"
q   essentially the opposite of is()
isnt() passing
isnt( 2 + 2, 5, 'Two plus two should not be five' );

ok 3 - Two plus two should not be five
isnt() failing
isnt( 2 + 2, 4, 'Two plus two should not be four' );

not ok 4 - Two plus two should not be four
#     Failed test (demotest.pl at line 10)
#     '4'
#         ne
#     '4'
1..4
matching things - like()
q   applies a regular expression to a string
q   first argument is the string
q   second argument is a regular expression
    x   compiled with qr//, where Perl version supports that
    x   a string that looks like a regex '/foo/', otherwise
like() passing
like( 'foobar', qr/fo+/,
'+ quantifier should match one or more' );

ok 5 - + quantifier should match one or more
like() failing
like( 'fbar', qr/fo+/,
'+ quantifier should match zero or more' );

not ok 6 - + quantifier should match zero or more
#     Failed test (demotest.pl at line 12)
#                   'fbar'
#     doesn't match '(?-xism:fo+)'
matching things - unlike()
q   essentially the opposite of like()
q   the same rules apply
unlike() passing
unlike( 'foobar', qr/baz/, 'foobar should not match baz' );

ok 7 - foobar should not match baz
unlike() failing
unlike( 'foobar', qr/bar/, 'foobar should not match bar' );

not ok 8 - foobar should not match bar
#     Failed test (demotest.pl at line 14)
#                   'foobar'
#           matches '(?-xism:bar)'
1..8
exploring behavior - use_ok()
q   (these tests all provide their own test names)
q   see if a module compiles and can be import()ed
q   load a module and import() it
q   activates at runtime, not compile time!
q   provides a default test name so you don't have to
q   allows optional imports to be passed
use_ok() passing
use_ok( 'Test::More' );

ok 11 - use Test::More;
use_ok() failing
use_ok( 'No::Module' );

not ok 12 - use No::Module;
#     Failed test (demotest.pl at line 20)
#     Tried to use 'No::Module'.
#     Error: Can't locate No/Module.pm in @INC (@INC
#     contains: /usr/lib/perl5/5.6.1/i386-linux
#     /usr/lib/perl5/5.6.1
#     /usr/lib/perl5/site_perl/5.6.1/i386-linux
#     /usr/lib/perl5/site_perl/5.6.1
#     /usr/lib/perl5/site_perl .) at (eval 6) line 2.
exploring behavior - require_ok()
q   see if a module compiles
q   load a module, but do not import() it
q   also provides a default test name
require_ok() passing
require_ok( 'Test::Simple' );

ok 13 - require Test::Simple;
require_ok() failing
require_ok( 'No::Module' );

not ok 14 - require No::Module;
#     Failed test (demotest.pl at line 23)
#     Tried to require 'No::Module'.
#     Error: Can't locate No/Module.pm in @INC (@INC
#     contains: /usr/lib/perl5/5.6.1/i386-linux
#     /usr/lib/perl5/5.6.1
#     /usr/lib/perl5/site_perl/5.6.1/i386-linux
#     /usr/lib/perl5/site_perl/5.6.1
#     /usr/lib/perl5/site_perl .) at (eval 8) line 2.
exploring behavior - isa_ok()
q   see if an object is a type of reference
q   can be an object
    x   but not a class
    x   it exists to save you from having to make three extra constructor
        tests
        Ë   did it return something defined?
        Ë   is that something a reference?
        Ë   is that reference an object?
q   respects inheritance
q   can be a reference type (scalar, array, hash, io, code)
isa_ok() passing
isa_ok( [], 'ARRAY' );

ok 15 - The object isa ARRAY
isa_ok() failing
isa_ok( {}, 'IO::Socket' );

not ok 16 - The object isa IO::Socket
#     Failed test (demotest.pl at line 26)
#     The object isn't a 'IO::Socket' it's a 'HASH'
exploring behavior - can_ok()
q   see if an object has named behavior(s)
q   can be an object or a class
q   pass several function or method names to test them all in a
    single test
q   loop over a can_ok() call to test them all in multiple tests
q   respects inheritance, but falls afoul of AUTOLOAD() just like
    UNIVERSAL::can() does
can_ok() passing
can_ok( 'Test::More', 'can_ok' );

ok 17 - Test::More->can('can_ok')
can_ok() failing
can_ok( 'Test::More', 'autotest' );

not ok 18 - Test::More->can('autotest')
#     Failed test (demotest.pl at line 29)
#     Test::More->can('autotest') failed
controlling things - skip()
q   skips a specified number of tests
q   generally used for things that will NEVER pass
q   takes the reason to skip the tests and the number to skip
q   should be in a labelled SKIP block
q   should have a skip condition
skip() in action
SKIP: {
   skip( 'Never on a Sunday', 2 ) if (localtime)[6] == 0;
can_ok( 'Perl::Porter', 'buy_beer' );
can_ok( 'Perl::Porter', 'wear_short_pants' );
}

ok 21 # skip Never on a Sunday
ok 22 # skip Never on a Sunday
controlling things - todo()
q   marks a specified number of tests as known failures
q   generally used for failures
    x   use sparingly!
    x   use for features that aren't quite finished
    x   use for bugs that aren't quite fixed
    x   don't let these add up: they undermine the suite
q   should be in a labelled TODO block
q   must localize the $TODO variable with the name
todo() in action
TODO: {
local $TODO = 'The alien overlords have not arrived';
is( $smallpox->status(), 'ready', 'Smallpox ready' );
ok( @cow_decoys > 1000, 'Bait ready...' );
}

not   ok 23 - Smallpox ready # TODO The alien overlords have
not   arrived
#       Failed (TODO) test (demotest.pl at line 46)
#             got: 'replenishing'
#       expected: 'ready'
not   ok 24 - Bait ready... # TODO The alien overlords have
not   arrived
#       Failed (TODO) test (demotest.pl at line 47)
controlling things - diag()
q   display a (list of) diagnostic message(s)
q   guaranteed not to interfere with the test harness
q   gives no test number, pass, or fail
q   useful for giving suggestions on tricky tests
diag() in action
diag( "Now that you know a bit about test writing,n",
        "you have no excuse not to test." );

# Now that you know a bit about test writing,
# you have no excuse not to test.
controlling things - pass()
q   make a test pass, unconditionally
q   takes a test name -- that's it!
pass() in action
pass( 'Executive fiat should work' );

ok 19 - Executive fiat should work
controlling things - fail()
q   makes a test fail, unconditionally
q   also takes a test name, and that's it
fail() in action
fail( '... but we live in a meritocracy' );

not ok 20 - ... but we live in a meritocracy
#     Failed test (demotest.pl at line 32)

Mais conteúdo relacionado

Mais procurados

TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019Paulo Clavijo
 
Refactoring legacy code driven by tests - ENG
Refactoring legacy code driven by tests - ENGRefactoring legacy code driven by tests - ENG
Refactoring legacy code driven by tests - ENGLuca Minudel
 
Mockito 2.x Migration - Droidcon UK 2018
Mockito 2.x Migration - Droidcon UK 2018Mockito 2.x Migration - Droidcon UK 2018
Mockito 2.x Migration - Droidcon UK 2018Hazem Saleh
 
TDD in Python With Pytest
TDD in Python With PytestTDD in Python With Pytest
TDD in Python With PytestEddy Reyes
 
Cpp Testing Techniques Tips and Tricks - Cpp Europe
Cpp Testing Techniques Tips and Tricks - Cpp EuropeCpp Testing Techniques Tips and Tricks - Cpp Europe
Cpp Testing Techniques Tips and Tricks - Cpp EuropeClare Macrae
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingDavid Rodenas
 
TDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleTDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleNoam Kfir
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy CodeAndrea Polci
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestSeb Rose
 
Automated testing in Python and beyond
Automated testing in Python and beyondAutomated testing in Python and beyond
Automated testing in Python and beyonddn
 
TDD in Go with Ginkgo and Gomega
TDD in Go with Ginkgo and GomegaTDD in Go with Ginkgo and Gomega
TDD in Go with Ginkgo and GomegaEddy Reyes
 
TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018Paulo Clavijo
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system Tarin Gamberini
 
Google test training
Google test trainingGoogle test training
Google test trainingThierry Gayet
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And RefactoringNaresh Jain
 
Mutation Testing
Mutation TestingMutation Testing
Mutation TestingESUG
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Hong Le Van
 

Mais procurados (20)

TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019TDD and Simple Design Workshop - Session 1 - March 2019
TDD and Simple Design Workshop - Session 1 - March 2019
 
Refactoring legacy code driven by tests - ENG
Refactoring legacy code driven by tests - ENGRefactoring legacy code driven by tests - ENG
Refactoring legacy code driven by tests - ENG
 
Mockito 2.x Migration - Droidcon UK 2018
Mockito 2.x Migration - Droidcon UK 2018Mockito 2.x Migration - Droidcon UK 2018
Mockito 2.x Migration - Droidcon UK 2018
 
TDD in Python With Pytest
TDD in Python With PytestTDD in Python With Pytest
TDD in Python With Pytest
 
Cpp Testing Techniques Tips and Tricks - Cpp Europe
Cpp Testing Techniques Tips and Tricks - Cpp EuropeCpp Testing Techniques Tips and Tricks - Cpp Europe
Cpp Testing Techniques Tips and Tricks - Cpp Europe
 
TDD CrashCourse Part1: Testing
TDD CrashCourse Part1: TestingTDD CrashCourse Part1: Testing
TDD CrashCourse Part1: Testing
 
TDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleTDD and the Legacy Code Black Hole
TDD and the Legacy Code Black Hole
 
Working With Legacy Code
Working With Legacy CodeWorking With Legacy Code
Working With Legacy Code
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
ES3-2020-05 Testing
ES3-2020-05 TestingES3-2020-05 Testing
ES3-2020-05 Testing
 
Automated testing in Python and beyond
Automated testing in Python and beyondAutomated testing in Python and beyond
Automated testing in Python and beyond
 
TAP In Depth
TAP In DepthTAP In Depth
TAP In Depth
 
TDD in Go with Ginkgo and Gomega
TDD in Go with Ginkgo and GomegaTDD in Go with Ginkgo and Gomega
TDD in Go with Ginkgo and Gomega
 
TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018TDD and Simple Design Workshop - Session 1 - November 2018
TDD and Simple Design Workshop - Session 1 - November 2018
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system
 
Google test training
Google test trainingGoogle test training
Google test training
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And Refactoring
 
Mutation Testing
Mutation TestingMutation Testing
Mutation Testing
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
 
클린 테스트
클린 테스트클린 테스트
클린 테스트
 

Destaque (7)

perl_tk_tutorial
perl_tk_tutorialperl_tk_tutorial
perl_tk_tutorial
 
perltut
perltutperltut
perltut
 
perl
perlperl
perl
 
PCCNews0609
PCCNews0609PCCNews0609
PCCNews0609
 
FOSE 2011: DNSSEC and the Government, Lessons Learned
FOSE 2011: DNSSEC and the Government, Lessons LearnedFOSE 2011: DNSSEC and the Government, Lessons Learned
FOSE 2011: DNSSEC and the Government, Lessons Learned
 
Presentatie alpe d_huzes_twinfield
Presentatie alpe d_huzes_twinfieldPresentatie alpe d_huzes_twinfield
Presentatie alpe d_huzes_twinfield
 
My Presentacion Oral.Pptx
My Presentacion Oral.PptxMy Presentacion Oral.Pptx
My Presentacion Oral.Pptx
 

Semelhante a IntroTestMore

Test tutorial
Test tutorialTest tutorial
Test tutorialmsksaba
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)Steve Upton
 
Debug - MITX60012016-V005100
Debug - MITX60012016-V005100Debug - MITX60012016-V005100
Debug - MITX60012016-V005100Ha Nguyen
 
Testing With Test::Class
Testing With Test::ClassTesting With Test::Class
Testing With Test::ClassCurtis Poe
 
Test Presentation
Test PresentationTest Presentation
Test Presentationsetitesuk
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
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
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)vilniusjug
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctlyDror Helper
 
Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Holger Grosse-Plankermann
 
Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Holger Grosse-Plankermann
 
2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easier2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easierChristian Hujer
 
Quality Assurance
Quality AssuranceQuality Assurance
Quality AssuranceKiran Kumar
 

Semelhante a IntroTestMore (20)

Test tutorial
Test tutorialTest tutorial
Test tutorial
 
Test-Tutorial
Test-TutorialTest-Tutorial
Test-Tutorial
 
Test-Tutorial
Test-TutorialTest-Tutorial
Test-Tutorial
 
Getting testy with Perl
Getting testy with PerlGetting testy with Perl
Getting testy with Perl
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)
 
Debug - MITX60012016-V005100
Debug - MITX60012016-V005100Debug - MITX60012016-V005100
Debug - MITX60012016-V005100
 
Testing With Test::Class
Testing With Test::ClassTesting With Test::Class
Testing With Test::Class
 
Test Presentation
Test PresentationTest Presentation
Test Presentation
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
Test Driven
Test DrivenTest Driven
Test Driven
 
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.
 
Dutch PHP Conference 2013: Distilled
Dutch PHP Conference 2013: DistilledDutch PHP Conference 2013: Distilled
Dutch PHP Conference 2013: Distilled
 
Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)Developer Tests - Things to Know (Vilnius JUG)
Developer Tests - Things to Know (Vilnius JUG)
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
Tdd - introduction
Tdd - introductionTdd - introduction
Tdd - introduction
 
Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018
 
Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018
 
2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easier2016 10-04: tdd++: tdd made easier
2016 10-04: tdd++: tdd made easier
 
Quality Assurance
Quality AssuranceQuality Assurance
Quality Assurance
 

Mais de tutorialsruby

<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />tutorialsruby
 
TopStyle Help & <b>Tutorial</b>
TopStyle Help & <b>Tutorial</b>TopStyle Help & <b>Tutorial</b>
TopStyle Help & <b>Tutorial</b>tutorialsruby
 
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>tutorialsruby
 
<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />tutorialsruby
 
<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />tutorialsruby
 
Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269tutorialsruby
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008tutorialsruby
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008tutorialsruby
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheetstutorialsruby
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheetstutorialsruby
 

Mais de tutorialsruby (20)

<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />
 
TopStyle Help & <b>Tutorial</b>
TopStyle Help & <b>Tutorial</b>TopStyle Help & <b>Tutorial</b>
TopStyle Help & <b>Tutorial</b>
 
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting <b>...</b>
 
<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />
 
<img src="../i/r_14.png" />
<img src="../i/r_14.png" /><img src="../i/r_14.png" />
<img src="../i/r_14.png" />
 
Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0
 
xhtml_basics
xhtml_basicsxhtml_basics
xhtml_basics
 
xhtml_basics
xhtml_basicsxhtml_basics
xhtml_basics
 
xhtml-documentation
xhtml-documentationxhtml-documentation
xhtml-documentation
 
xhtml-documentation
xhtml-documentationxhtml-documentation
xhtml-documentation
 
CSS
CSSCSS
CSS
 
CSS
CSSCSS
CSS
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
 
HowTo_CSS
HowTo_CSSHowTo_CSS
HowTo_CSS
 
HowTo_CSS
HowTo_CSSHowTo_CSS
HowTo_CSS
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheets
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheets
 

Último

Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 

Último (20)

Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 

IntroTestMore

  • 1. A Perl Testing Tutorial chromatic
  • 3. ensure the code does what it should do q no missing functionality q no accidental functionality q when your tests all pass, you're done
  • 4. explore boundary conditions q how does the code handle bad input? q how does the code handle very bad input?
  • 5. prevent (known) regressions q no tested features can be broken accidentally q no fixed bugs can reoccur
  • 6. improve bug reports q test output can pinpoint errors q easily generated by end users run this and send me the output
  • 7. enable refactoring q you break it, you know it right away q side effects immediately evident q well-tested code tends to be more modular x I had several pre-existing modules with similar behavior to test. They were only tangentially related. After the second test suite turned out almost the same, I realized I needed a parent class. I moved most of the tests to the parent class and the inherited classes ended up much simpler and very much shorter. Their tests were much simpler, too. This gave me less code to maintain, fewer tests to write, and more flexibility for adding new features.
  • 8. improve API q hard to test code may be hard to use q writing a test first forces you to use the interface before you create it x simpler interfaces are easier to test x smaller functions are easier to reuse
  • 9. promote automation x easy to test code is usually well-decoupled x easy to test code is, by definition, scriptable
  • 10. ease maintainability q tests are a safety net x if you don't understand this by now, I'll repeat it once again q well-written tests serve as a sort of documentation x demonstrate what features the software should have x demonstrate what behavior the code should express
  • 12. Don't be Scared! q writing good tests exercises the same muscles as writing good code q if you can write code, you can write tests q if you can write good code, you can be taught to write good tests
  • 13. Testing Has Psychological Benefits q writing tests (especially test first) makes it easier to write tests q well-tested code is more fun to hack q test-first programming gives instant feedback q that's instant positive feedback, most of the time
  • 14. Perl makes it easy q ExtUtils::MakeMaker and the 'test' target q Test::* modules hide the Test::Harness expectations q if lazy dopes like us can do it, you can too!
  • 16. Thinking "ok" print "ok"; print "not ok"; q basis for all tests q a simple boolean condition q generally numbered sequentially
  • 17. More thinking "ok" q why printing is a loss: x same arguments as using subroutines (duplicate code) x manual test renumbering x no diagnostics unless you provide them Ë what matched Ë what didn't match Ë which test failed and where x no built-in provision for more complex constructs x can be hard to maintain
  • 18. The ok() function ok( 1 == 1 ); q basis for all Test::Simple, Test::More, Test::Builder tests q a simple boolean condition q why it's a win: x alleviates duplicate code x associates a name with a test x expresses test intent more clearly x avoids portability concerns
  • 20. planning tests q helps catch too many/not enough test errors q helps identify which test fails q required by Test::Harness use Test::Simple tests => 10; use Test::Simple 'no_plan';
  • 21. tests => n q produces 1..n output for Test::Harness q should be set when the test suite is complete
  • 22. no_plan q produces 1..actual output at the end of the test q when you don't know how many tests will run q very handy while developing a module q not so handy when distributing a module
  • 23. ok() q scalar context of operands q first argument always true or false q second argument optional, test name q condition is code expression of the test name q test name is a declaration of the intent of the condition
  • 24. ok() passing ok( 1, '1 should be true' ); ok 1 - 1 should be true
  • 25. ok() failing ok( 0, '0 should be true' ); not ok 2 - 0 should be true # Failed test (demotest.pl at line 17)
  • 26. success is not a gray area (individual tests) q pass, or fail, there is no maybe q test the smallest piece possible q test one thing at a time q pass quietly x avoid errors x avoid warnings x test for errors and warnings if you must
  • 27. success is all or nothing (test suite) q stamp out expected failures x undermine confidence in the code x clutter up screens and logs x hide new problems q keeping changes small helps localize damage q keeping tests working helps localize damage q there are ways to isolate platform-specific tests
  • 28. Integrating testing with the development process
  • 29. catching regressions q most bugs aren't new, they happen again and again q why let them reoccur? q write a test for every new bug
  • 30. testing first q teeny, tiny, mini-iterations q break each task into boolean expressions q "What feature do I need next?" x smallest element of overall task x one small step at a time
  • 31. The two test-first questions q "How can I prove that this feature works?" x the simplest test that will fail unless the feature works x THE TEST MUST FAIL q "What is the least amount of code I can write to pass the test?" x the simpler the test, the simpler the code you need x THE TEST MUST NOW PASS q this produces known good code and a comprehensive test suite q be sure to run the entire test suite after you implement a task
  • 32. writing testable code q the smaller the unit, the better q the simpler the unit, the better q the better the test suite, the easier it is to refactor q writing your tests first promotes this!
  • 33. distributing tests q Test.pm is easier to distribute x single module, does not depend on Test::Builder x compatible with Test::More API q Test::Simple suite can be bundled with module x CGI.pm does this, among others q Test::Simple ships with 5.8 q a module can depend on Test::Simple
  • 35. graduating from Test::Simple to Test::More, or why ok() is not enough q one bit of data -- either it passed or it failed q contains little debugging information x what did you get? x what did you receive? x do you really want to exchange "add a print at line 43" emails? q true laziness is a sign of good testing
  • 36. matching things - is() q asks the question "are these two things equal?" q does a pretty good job of guessing at the type of equality q takes an optional test name, so use one q special cased for 'undef'
  • 37. is() passing is( 2 + 2, 4, 'Two plus two should be four' ); ok 1 - Two plus two should be four
  • 38. is() failing is( 2 + 2, 5, 'Two plus two should be five' ); not ok 2 - Two plus two should be five # Failed test (demotest.pl at line 8) # got: '4' # expected: '5'
  • 39. matching things - isnt() q asks the question "are these two things not equal?" q essentially the opposite of is()
  • 40. isnt() passing isnt( 2 + 2, 5, 'Two plus two should not be five' ); ok 3 - Two plus two should not be five
  • 41. isnt() failing isnt( 2 + 2, 4, 'Two plus two should not be four' ); not ok 4 - Two plus two should not be four # Failed test (demotest.pl at line 10) # '4' # ne # '4' 1..4
  • 42. matching things - like() q applies a regular expression to a string q first argument is the string q second argument is a regular expression x compiled with qr//, where Perl version supports that x a string that looks like a regex '/foo/', otherwise
  • 43. like() passing like( 'foobar', qr/fo+/, '+ quantifier should match one or more' ); ok 5 - + quantifier should match one or more
  • 44. like() failing like( 'fbar', qr/fo+/, '+ quantifier should match zero or more' ); not ok 6 - + quantifier should match zero or more # Failed test (demotest.pl at line 12) # 'fbar' # doesn't match '(?-xism:fo+)'
  • 45. matching things - unlike() q essentially the opposite of like() q the same rules apply
  • 46. unlike() passing unlike( 'foobar', qr/baz/, 'foobar should not match baz' ); ok 7 - foobar should not match baz
  • 47. unlike() failing unlike( 'foobar', qr/bar/, 'foobar should not match bar' ); not ok 8 - foobar should not match bar # Failed test (demotest.pl at line 14) # 'foobar' # matches '(?-xism:bar)' 1..8
  • 48. exploring behavior - use_ok() q (these tests all provide their own test names) q see if a module compiles and can be import()ed q load a module and import() it q activates at runtime, not compile time! q provides a default test name so you don't have to q allows optional imports to be passed
  • 49. use_ok() passing use_ok( 'Test::More' ); ok 11 - use Test::More;
  • 50. use_ok() failing use_ok( 'No::Module' ); not ok 12 - use No::Module; # Failed test (demotest.pl at line 20) # Tried to use 'No::Module'. # Error: Can't locate No/Module.pm in @INC (@INC # contains: /usr/lib/perl5/5.6.1/i386-linux # /usr/lib/perl5/5.6.1 # /usr/lib/perl5/site_perl/5.6.1/i386-linux # /usr/lib/perl5/site_perl/5.6.1 # /usr/lib/perl5/site_perl .) at (eval 6) line 2.
  • 51. exploring behavior - require_ok() q see if a module compiles q load a module, but do not import() it q also provides a default test name
  • 52. require_ok() passing require_ok( 'Test::Simple' ); ok 13 - require Test::Simple;
  • 53. require_ok() failing require_ok( 'No::Module' ); not ok 14 - require No::Module; # Failed test (demotest.pl at line 23) # Tried to require 'No::Module'. # Error: Can't locate No/Module.pm in @INC (@INC # contains: /usr/lib/perl5/5.6.1/i386-linux # /usr/lib/perl5/5.6.1 # /usr/lib/perl5/site_perl/5.6.1/i386-linux # /usr/lib/perl5/site_perl/5.6.1 # /usr/lib/perl5/site_perl .) at (eval 8) line 2.
  • 54. exploring behavior - isa_ok() q see if an object is a type of reference q can be an object x but not a class x it exists to save you from having to make three extra constructor tests Ë did it return something defined? Ë is that something a reference? Ë is that reference an object? q respects inheritance q can be a reference type (scalar, array, hash, io, code)
  • 55. isa_ok() passing isa_ok( [], 'ARRAY' ); ok 15 - The object isa ARRAY
  • 56. isa_ok() failing isa_ok( {}, 'IO::Socket' ); not ok 16 - The object isa IO::Socket # Failed test (demotest.pl at line 26) # The object isn't a 'IO::Socket' it's a 'HASH'
  • 57. exploring behavior - can_ok() q see if an object has named behavior(s) q can be an object or a class q pass several function or method names to test them all in a single test q loop over a can_ok() call to test them all in multiple tests q respects inheritance, but falls afoul of AUTOLOAD() just like UNIVERSAL::can() does
  • 58. can_ok() passing can_ok( 'Test::More', 'can_ok' ); ok 17 - Test::More->can('can_ok')
  • 59. can_ok() failing can_ok( 'Test::More', 'autotest' ); not ok 18 - Test::More->can('autotest') # Failed test (demotest.pl at line 29) # Test::More->can('autotest') failed
  • 60. controlling things - skip() q skips a specified number of tests q generally used for things that will NEVER pass q takes the reason to skip the tests and the number to skip q should be in a labelled SKIP block q should have a skip condition
  • 61. skip() in action SKIP: { skip( 'Never on a Sunday', 2 ) if (localtime)[6] == 0; can_ok( 'Perl::Porter', 'buy_beer' ); can_ok( 'Perl::Porter', 'wear_short_pants' ); } ok 21 # skip Never on a Sunday ok 22 # skip Never on a Sunday
  • 62. controlling things - todo() q marks a specified number of tests as known failures q generally used for failures x use sparingly! x use for features that aren't quite finished x use for bugs that aren't quite fixed x don't let these add up: they undermine the suite q should be in a labelled TODO block q must localize the $TODO variable with the name
  • 63. todo() in action TODO: { local $TODO = 'The alien overlords have not arrived'; is( $smallpox->status(), 'ready', 'Smallpox ready' ); ok( @cow_decoys > 1000, 'Bait ready...' ); } not ok 23 - Smallpox ready # TODO The alien overlords have not arrived # Failed (TODO) test (demotest.pl at line 46) # got: 'replenishing' # expected: 'ready' not ok 24 - Bait ready... # TODO The alien overlords have not arrived # Failed (TODO) test (demotest.pl at line 47)
  • 64. controlling things - diag() q display a (list of) diagnostic message(s) q guaranteed not to interfere with the test harness q gives no test number, pass, or fail q useful for giving suggestions on tricky tests
  • 65. diag() in action diag( "Now that you know a bit about test writing,n", "you have no excuse not to test." ); # Now that you know a bit about test writing, # you have no excuse not to test.
  • 66. controlling things - pass() q make a test pass, unconditionally q takes a test name -- that's it!
  • 67. pass() in action pass( 'Executive fiat should work' ); ok 19 - Executive fiat should work
  • 68. controlling things - fail() q makes a test fail, unconditionally q also takes a test name, and that's it
  • 69. fail() in action fail( '... but we live in a meritocracy' ); not ok 20 - ... but we live in a meritocracy # Failed test (demotest.pl at line 32)