SlideShare a Scribd company logo
1 of 51
Download to read offline
From typing the test to testing the type Wim Godden Cu.be Solutions User meeting Aug 25, 2010
About me ,[object Object]
PHP developer since 1997 (PHP/FI 2.0)
ZCE and ZFCE
Developer of OpenX
Owner of Cu.be Solutions
Currently : PHP Architect @ NMBS
About you ,[object Object]
OOP experience ?
Testing : ,[object Object]
Have you written any ?
Brief agenda ,[object Object]
How does it work ?
When and how to test
A complete example (with some pitfalls)
Some hints & tips along the way
Testing the type
This is not... ,[object Object]
a complete step-by-step guide
a typical unit testing presentation (as you'll notice...)
-> Plenty of online resources, tutorials, conference talks, etc. about the regular stuff
What's unit testing ? ,[object Object]
What's unit testing ? ,[object Object]
What's a unit ? <?php class  Fridge { protected  $beerBottles ; public function  getBeerSupply() { return  $this ->beerBottles; } public function  addBeer( $bottles ) { $this ->beerBottles +=  $bottles ; return true ; } public function  drinkBeer( $bottles ) { $this ->beerBottles -=  $bottles ; return true ; } }
Why unit test ? ,[object Object]
Add code
Add more code
At some point you will break something ,[object Object]
Typos (= instead of == in an if-statement)
Backwards logic (== instead of !=, < instead of >)
etc. ,[object Object],[object Object]
Why unit test ? ,[object Object],[object Object],[object Object]
Why unit test ? ,[object Object]
-> if a test fails, you know exactly where to look
Early detection of bugs
Tests are : ,[object Object]
repeatable
consistent ,[object Object]
Unit tests -> “this is what's wrong in this piece of code”
A simple example <?php class  Fridge { protected  $beerBottles ; public function  addBeer( $bottles ) { $this ->beerBottles +=  $bottles ; return true ; } public function  drinkBeer( $bottles ) { if  ( $bottles  >=  $this ->beerBottles) { $this ->beerBottles -=  $bottles ; return true ; }  else  {  // We ran out of beer ! // $wive->sendToStore($beer, 'a lot'); return false ; } } public function  getBeerSupply() { return  $this ->beerBottles; } } <?php class  FridgeTest  extends  PHPUnit_Framework_TestCase { private  $fridge ; public function  testAddBeer() { $this ->fridge =  new  Fridge(); $this ->assertTrue( $this ->fridge->addBeer( 15 )); } public function  testDrinkBeer() { $this ->fridge =  new  Fridge(); $this ->assertTrue( $this ->fridge->drinkBeer( 15 )); } public function  testGetBeerSupply() { $this ->fridge =  new  Fridge(); $this ->assertType( 'integer' , $this ->fridge->getBeerSupply() ); } }
How does it work ?
Running the test ,[object Object]
Output :
...
Time: 0 seconds
OK (3 tests, 3 assertions)
Assertions ,[object Object]
AssertTrue
AssertFalse
AssertType
AssertGreaterThan

More Related Content

What's hot

Bad test, good test
Bad test, good testBad test, good test
Bad test, good testSeb Rose
 
Unit-Testing Bad-Practices by Example
Unit-Testing Bad-Practices by ExampleUnit-Testing Bad-Practices by Example
Unit-Testing Bad-Practices by ExampleBenjamin Eberlei
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Michelangelo van Dam
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013Michelangelo van Dam
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best PracticesEdorian
 
Unit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon GaliciaUnit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon GaliciaRobot Media
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentationnicobn
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
ISSTA 2010 Presentation
ISSTA 2010 PresentationISSTA 2010 Presentation
ISSTA 2010 PresentationJulian Dolby
 
Testing My Patience
Testing My PatienceTesting My Patience
Testing My PatienceAdam Lowry
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmanndpc
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)ENDelt260
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 

What's hot (20)

Bad test, good test
Bad test, good testBad test, good test
Bad test, good test
 
Unit-Testing Bad-Practices by Example
Unit-Testing Bad-Practices by ExampleUnit-Testing Bad-Practices by Example
Unit-Testing Bad-Practices by Example
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
 
PhpUnit Best Practices
PhpUnit Best PracticesPhpUnit Best Practices
PhpUnit Best Practices
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Unit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon GaliciaUnit testing en iOS @ MobileCon Galicia
Unit testing en iOS @ MobileCon Galicia
 
A Test of Strength
A Test of StrengthA Test of Strength
A Test of Strength
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Unit Testing Presentation
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
ISSTA 2010 Presentation
ISSTA 2010 PresentationISSTA 2010 Presentation
ISSTA 2010 Presentation
 
Testing My Patience
Testing My PatienceTesting My Patience
Testing My Patience
 
New Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian BergmannNew Features PHPUnit 3.3 - Sebastian Bergmann
New Features PHPUnit 3.3 - Sebastian Bergmann
 
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)Unlock The Mystery Of PHPUnit (Wave PHP 2018)
Unlock The Mystery Of PHPUnit (Wave PHP 2018)
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 

Viewers also liked

Caching and tuning fun for high scalability @ 4Developers
Caching and tuning fun for high scalability @ 4DevelopersCaching and tuning fun for high scalability @ 4Developers
Caching and tuning fun for high scalability @ 4DevelopersWim Godden
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalabilityWim Godden
 
Nginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your siteNginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your siteWim Godden
 
Making dynamic sites scale like static sites
Making dynamic sites scale like static sitesMaking dynamic sites scale like static sites
Making dynamic sites scale like static sitesWim Godden
 
Remove web calls and scale your site like crazy !
Remove web calls and scale your site like crazy !Remove web calls and scale your site like crazy !
Remove web calls and scale your site like crazy !Wim Godden
 
Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)
Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)
Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)Wim Godden
 

Viewers also liked (6)

Caching and tuning fun for high scalability @ 4Developers
Caching and tuning fun for high scalability @ 4DevelopersCaching and tuning fun for high scalability @ 4Developers
Caching and tuning fun for high scalability @ 4Developers
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
Nginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your siteNginx and friends - putting a turbo button on your site
Nginx and friends - putting a turbo button on your site
 
Making dynamic sites scale like static sites
Making dynamic sites scale like static sitesMaking dynamic sites scale like static sites
Making dynamic sites scale like static sites
 
Remove web calls and scale your site like crazy !
Remove web calls and scale your site like crazy !Remove web calls and scale your site like crazy !
Remove web calls and scale your site like crazy !
 
Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)
Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)
Creating fast, dynamic ACLs in Zend Framework (Zend Webinar)
 

Similar to From typing the test to testing the type

Using of TDD practices for Magento
Using of TDD practices for MagentoUsing of TDD practices for Magento
Using of TDD practices for MagentoIvan Chepurnyi
 
Testing persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitTesting persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitPeter Wilcsinszky
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Test Infected Presentation
Test Infected PresentationTest Infected Presentation
Test Infected Presentationwillmation
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014Guillaume POTIER
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Symfony (Unit, Functional) Testing.
Symfony (Unit, Functional) Testing.Symfony (Unit, Functional) Testing.
Symfony (Unit, Functional) Testing.Basel Issmail
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend TestingNeil Crosby
 
Pro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise ApplicationsPro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise ApplicationsStephen Chin
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit TestingMike Lively
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example usingIevgenii Katsan
 
Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Bernhard Schussek
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit TestingMike Lively
 
Bdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infiniteBdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infiniteGiordano Scalzo
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 

Similar to From typing the test to testing the type (20)

PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Using of TDD practices for Magento
Using of TDD practices for MagentoUsing of TDD practices for Magento
Using of TDD practices for Magento
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
Testing persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitTesting persistence in PHP with DbUnit
Testing persistence in PHP with DbUnit
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Test Infected Presentation
Test Infected PresentationTest Infected Presentation
Test Infected Presentation
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Symfony (Unit, Functional) Testing.
Symfony (Unit, Functional) Testing.Symfony (Unit, Functional) Testing.
Symfony (Unit, Functional) Testing.
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Pro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise ApplicationsPro Java Fx – Developing Enterprise Applications
Pro Java Fx – Developing Enterprise Applications
 
Advanced PHPUnit Testing
Advanced PHPUnit TestingAdvanced PHPUnit Testing
Advanced PHPUnit Testing
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example using
 
Best Practice Testing with Lime 2
Best Practice Testing with Lime 2Best Practice Testing with Lime 2
Best Practice Testing with Lime 2
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Automated Unit Testing
Automated Unit TestingAutomated Unit Testing
Automated Unit Testing
 
Bdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infiniteBdd: Tdd and beyond the infinite
Bdd: Tdd and beyond the infinite
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 

More from Wim Godden

Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to lifeWim Godden
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8Wim Godden
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websocketsWim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to lifeWim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developersWim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.xWim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.xWim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websocketsWim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developersWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 

More from Wim Godden (20)

Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 

Recently uploaded

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 

Recently uploaded (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

From typing the test to testing the type

  • 1. From typing the test to testing the type Wim Godden Cu.be Solutions User meeting Aug 25, 2010
  • 2.
  • 3. PHP developer since 1997 (PHP/FI 2.0)
  • 6. Owner of Cu.be Solutions
  • 7. Currently : PHP Architect @ NMBS
  • 8.
  • 10.
  • 12.
  • 13. How does it work ?
  • 14. When and how to test
  • 15. A complete example (with some pitfalls)
  • 16. Some hints & tips along the way
  • 18.
  • 20. a typical unit testing presentation (as you'll notice...)
  • 21. -> Plenty of online resources, tutorials, conference talks, etc. about the regular stuff
  • 22.
  • 23.
  • 24. What's a unit ? <?php class Fridge { protected $beerBottles ; public function getBeerSupply() { return $this ->beerBottles; } public function addBeer( $bottles ) { $this ->beerBottles += $bottles ; return true ; } public function drinkBeer( $bottles ) { $this ->beerBottles -= $bottles ; return true ; } }
  • 25.
  • 28.
  • 29. Typos (= instead of == in an if-statement)
  • 30. Backwards logic (== instead of !=, < instead of >)
  • 31.
  • 32.
  • 33.
  • 34. -> if a test fails, you know exactly where to look
  • 36.
  • 38.
  • 39. Unit tests -> “this is what's wrong in this piece of code”
  • 40. A simple example <?php class Fridge { protected $beerBottles ; public function addBeer( $bottles ) { $this ->beerBottles += $bottles ; return true ; } public function drinkBeer( $bottles ) { if ( $bottles >= $this ->beerBottles) { $this ->beerBottles -= $bottles ; return true ; } else { // We ran out of beer ! // $wive->sendToStore($beer, 'a lot'); return false ; } } public function getBeerSupply() { return $this ->beerBottles; } } <?php class FridgeTest extends PHPUnit_Framework_TestCase { private $fridge ; public function testAddBeer() { $this ->fridge = new Fridge(); $this ->assertTrue( $this ->fridge->addBeer( 15 )); } public function testDrinkBeer() { $this ->fridge = new Fridge(); $this ->assertTrue( $this ->fridge->drinkBeer( 15 )); } public function testGetBeerSupply() { $this ->fridge = new Fridge(); $this ->assertType( 'integer' , $this ->fridge->getBeerSupply() ); } }
  • 41. How does it work ?
  • 42.
  • 44. ...
  • 46. OK (3 tests, 3 assertions)
  • 47.
  • 53.
  • 54. You can also add your own !
  • 55.
  • 56. Tests should run independent of the result of a previous test
  • 57.
  • 59.
  • 60. Fill the fridge with 15 beers
  • 61.
  • 62. Fill the fridge with 15 beers
  • 63. Run the test (see if there's 15 beers in the fridge)
  • 65.
  • 66.
  • 67. Fill the fridge with 15 beers
  • 68.
  • 69.
  • 70.
  • 71. Fill the fridge with 15 beers
  • 72. Run the test (see if there's 15 beers in the fridge)
  • 73.
  • 74.
  • 82. tearDown() class FridgeTest extends PHPUnit_Framework_TestCase { private $fridge ; protected function setUp() { $this ->fridge = new Fridge(); } protected function tearDown() { $this ->fridge->drinkBeer( $this ->fridge->getBeerSupply() ); } public function testAddBeer() { $this ->assertTrue( $this ->fridge->addBeer( 15 )); } public function testDrinkBeer() { $this ->assertTrue( $this ->fridge->drinkBeer( 15 )); } public function testGetBeerSupply() { $this ->assertType( 'integer' , $this ->fridge->getBeerSupply() ); } }
  • 83. The do's and dont's class User { protected $age ; public function getAge() { return $this ->age; } public function setAge( $newAge ) { if ( $newAge ) { if ( $newAge >= 0 && $newAge <= 150 ) { $this ->age = $newAge ; return true ; } else { return false ; } } else { return false ; } } } class UserTest extends PHPUnit_Framework_TestCase { private $User ; protected function setUp() { $this ->User = new User(); } public function testGetAge() { $this ->assertType( 'integer' , $this ->User->getAge()); } protected static function provideAges() { return array ( array (rand( 0 , 150 )), array (rand( 0 , 150 )), array (rand( 0 , 150 )) ); } /** * @dataProvider provideAges */ public function testSetAge( $age ) { $this ->assertTrue( $this ->User->setAge( $age )); }
  • 84.
  • 86. What about empty string ? Null ? protected static function provideInvalidAges() { return array ( array (- 1 ), array ( 151 ), array ( &quot;not an int&quot; ), array ( &quot;&quot; ), array (NULL) ); } /** * @dataProvider provideInvalidAges */ public function testSetAgeInvalid( $age ) { $this ->assertFalse( $this ->User->setAge( $age )); }
  • 87. Good test ? protected static function provideAges() { return array ( array (rand( 0 , 150 )), array (rand( 0 , 150 )), array (rand( 0 , 150 )) ); } /** * @dataProvider provideAges */ public function testSetAge( $age ) { $this ->assertTrue( $this ->User->setAge( $age )); } protected static function provideInvalidAges() { return array ( array (- 1 ), array ( 151 ), array ( &quot;not an int&quot; ), array ( &quot;&quot; ), array (NULL) ); } /** * @dataProvider provideInvalidAges */ public function testSetAgeInvalid( $age ) { $this ->assertFalse( $this ->User->setAge( $age )); }
  • 89. Bug in the test or the code ? public function setAge( $newAge ) { if ( $newAge ) { if ( $newAge >= 0 && $newAge <= 150 ) { $this ->age = $newAge ; return true ; } else { return false ; } } else { return false ; } } protected static function provideAges() { return array ( array (rand( 0 , 150 )), array (rand( 0 , 150 )), array (rand( 0 , 150 )) ); } /** * @dataProvider provideAges */ public function testSetAge( $age ) { $this ->assertTrue( $this ->User->setAge( $age )); }
  • 90. Bug in the code ! public function setAge( $newAge ) { if (is_int( $newAge )) { if ( $newAge >= 0 && $newAge <= 150 ) { $this ->age = $newAge ; return true ; } else { return false ; } } else { return false ; } } protected static function provideAges() { return array ( array (rand( 0 , 150 )), array (rand( 0 , 150 )), array (rand( 0 , 150 )) ); } /** * @dataProvider provideAges */ public function testSetAge( $age ) { $this ->assertTrue( $this ->User->setAge( $age )); }
  • 91. The code was buggy... what about the test ?
  • 92.
  • 93. always test edge cases
  • 94.
  • 96.
  • 97. -> We're just checking if setAge() returns true or false ! protected static function provideAges() { return array ( array ( 0 ), array (rand( 1 , 149 )), array (rand( 1 , 149 )), array (rand( 1 , 149 )), array ( 150 ) ); }
  • 98. Good tests... public function testSetAgeActuallySets() { $newAge = mt_rand( 0 , 150 ); $this ->User->setAge( $newAge ); $this ->assertEquals( $newAge , $this ->User->getAge() ); } Good tests don't just cover code... they test the functionality of the code !
  • 99.
  • 104.
  • 105. How NOT to test try { $billingAddress = new Address(&quot;Meir 12&quot;, 2000, &quot;Antwerpen&quot;, &quot;BE&quot;); $officeAddress = new Address(&quot;Groenplaats 50&quot;, 2000, &quot;Antwerpen&quot;, &quot;BE&quot;); $customer = new Customer(402, &quot;Jan&quot;, &quot;De Man&quot;, 32, $billingAddress, $officeAddress); $product = new Product(92, &quot;Speculaas&quot;, 5.95); $invoice = new Invoice($customer); $invoice.addItemQuantity($product, 5); $lineItems = $invoice.getLineitems(); if ($lineItems.size() == 1) { $actualLineItem = $lineItems.get(0); $this->assertEquals($invoice, $actualLineItem.getInvoice()); $this->assertEquals($product, $actualLineItem.getProduct()); $this->assertEquals($quantity, $actualLineItem, getQuantity()); $this->assertEquals(5.95, $actualLineItem.getUnitPrice()); } else { $this->assertTrue(false, 'Invoice should have exactly one line item'); } deleteObject($invoice); deleteObject($product); deleteObject($customer); deleteObject($billingAddress); deleteObject($officeAddress); } catch (Exception $e) { // Whatever }
  • 106. How NOT to test try { $billingAddress = new Address(&quot;Meir 12&quot;, 2000, &quot;Antwerpen&quot;, &quot;BE&quot;); $officeAddress = new Address(&quot;Groenplaats 50&quot;, 2000, &quot;Antwerpen&quot;, &quot;BE&quot;); $customer = new Customer(402, &quot;Jan&quot;, &quot;De Man&quot;, 32, $billingAddress, $officeAddress); $product = new Product(92, &quot;Speculaas&quot;, 5.95); $invoice = new Invoice($customer); $invoice.addItemQuantity($product, 5); $lineItems = $invoice.getLineitems(); $this->assertEquals(1, $lineItems.size()); $actualLineItem = $lineItems.get(0); $this->assertEquals($invoice, $actualLineItem.getInvoice()); $this->assertEquals($product, $actualLineItem.getProduct()); $this->assertEquals($quantity, $actualLineItem, getQuantity()); $this->assertEquals(5.95, $actualLineItem.getUnitPrice()); deleteObject($invoice); deleteObject($product); deleteObject($customer); deleteObject($billingAddress); deleteObject($officeAddress); } catch (Exception $e) { // Whatever }
  • 107. How NOT to test try { $billingAddress = new Address(&quot;Meir 12&quot;, 2000, &quot;Antwerpen&quot;, &quot;BE&quot;); $officeAddress = new Address(&quot;Groenplaats 50&quot;, 2000, &quot;Antwerpen&quot;, &quot;BE&quot;); $customer = new Customer(402, &quot;Jan&quot;, &quot;De Man&quot;, 32, $billingAddress, $officeAddress); $product = new Product(92, &quot;Speculaas&quot;, 5.95); $invoice = new Invoice($customer); $invoice.addItemQuantity($product, 5); $lineItems = $invoice.getLineitems(); $this->assertEquals(1, $lineItems.size()); $actualLineItem = $lineItems.get(0); $this->assertEquals($invoice, $actualLineItem.getInvoice()); $this->assertEquals($product, $actualLineItem.getProduct()); $this->assertEquals($quantity, $actualLineItem, getQuantity()); $this->assertEquals(5.95, $actualLineItem.getUnitPrice()); try { deleteObject($invoice); } catch (Exception $e) { // Whatever } try { deleteObject($product); } catch (Exception $e) { // Whatever } try { deleteObject($customer); } catch (Exception $e) { // Whatever } try { deleteObject($billingAddress); } catch (Exception $e) { // Whatever } try { deleteObject($officeAddress); } catch (Exception $e) { // Whatever } } catch (Exception $e) { // Whatever }
  • 108.
  • 109. Replace the unneeded data protected $testObjects; public function testInvoice() { $billingAddress = new TestAddress(); $this->addTestObject($billingAddress); $officeAddress = new TestAddress(); $this->addTestObject($officeAddress); $customer = new TestCustomer($billingAddress, $officeAddress); $this->addTestObject($customer); $product = new Product(92, &quot;Speculaas&quot;, 5.95); $this->addTestObject($product); $invoice = new Invoice($customer); $this->addTestObject($invoice); $invoice.addItemQuantity($product, 5); $lineItems = $invoice.getLineitems(); $this->assertEquals(1, $lineItems.size()); $actualLineItem = $lineItems.get(0); $this->assertEquals($invoice, $actualLineItem.getInvoice()); $this->assertEquals($product, $actualLineItem.getProduct()); $this->assertEquals($quantity, $actualLineItem, getQuantity()); $this->assertEquals(5.95, $actualLineItem.getUnitPrice()); } public function tearDown() { $this->deleteTestObjects(); }
  • 110.
  • 111. Until you look at the Invoice class
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 119.
  • 120. then
  • 121.
  • 122. Write the test first -> code will do what the test dictates
  • 125.
  • 126.
  • 127.
  • 128. We typed the test... Now let's test the type !
  • 129.
  • 130. Allows type validation during unit testing
  • 131. Time it took to build : a few days
  • 132.
  • 133. See the magic happen
  • 134.
  • 135. When the method is called from our test, it compares the type of each parameter with the type in the docblock :
  • 136. The result : /** * Cat constructor * @param string $name The name of the cat * @param int $lives The number of lives this cat has left */ PHPUnit 3.5 by Sebastian Bergmann. FF... Time: 1 second, Memory: 3.25Mb There were 2 failures: 1) CatTest::test__constructWithNegativeLives Invalid type calling Cat->__construct : parameter 1 ($name) should be of type string but got bool instead in /home/dev/paramtest/tests/CatTest.php 2) CatTest::test__constructWithNegativeLives Invalid type calling Cat->__construct : parameter 2 ($lives) should be of type int but got string instead in /home/dev/paramtest/tests/CatTest.php FAILURES! Tests: 5, Assertions: 8, Failures: 2. $cat = new Cat(true, &quot;9&quot;);
  • 137.
  • 138.
  • 139.
  • 140.
  • 141. (and it forces you to keep the docblock updated,
  • 142. which is good for API documentation quality !)
  • 143.
  • 144. Click on 'Download Source'
  • 146. > php <path-to-phpunit.php> --check-param-types <your-test.php>
  • 147. Be amazed at how many type issues you have ;-)
  • 148.
  • 149. Slows down unit tests by factor of 2.5
  • 150.
  • 151.
  • 152.
  • 153. Always test the edge cases
  • 154.
  • 155. Test your types for consistency
  • 156. -> Unit tests take a developer from :
  • 158. to
  • 159. I can prove it works
  • 160.
  • 161. Spinoff of FirstLink Networks (founded in 2000)
  • 164. Contribute to open source projects
  • 165. (ZF, Xdebug, PHPUnit, OpenX, ...)
  • 169.
  • 170.
  • 171.
  • 172.

Editor's Notes

  1. It&apos;s not the responsibility of the class to create the new classes, it&apos;s the responsibility of the callee to provide these objects. For example : an object using a cache should not instantiate the cache, nor do cache::getInstance, instead the cache object should be provided to the object.