SlideShare uma empresa Scribd logo
1 de 29
Testing persistence (in PHP) PHPUnit & DbUnit
Our story by unit testing classes Started from inside to the outside
Tools and principles Using PHPUnit with Mock objects  to isolate the SUT ,[object Object],[object Object],[object Object],http://xunitpatterns.com/Principles of Test Automation.html http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
PHPUnit class   TestClass        extends  PHPUnit_Framework_TestCase {      public   function   setUp () {}      public   function   testMethod () {}      public   function   tearDown () {} }
Problems No integration guarantees Not effective for refactoring legacy code Does not ensure external quality
Need for integration tests To ensure external quality from top to bottom
Unit testing DAOs with DI and mocks $connection   =  createMockExpecting(      " INSERT INTO table SET field = 'value' " ); $dao   =   new  Dao( $connection ); $dao -> insert ( 'value' ); Tells nothing about the database interaction
Testing DAOs - injected connection $connection   =  createLocalTestConnection(); $dao   =   new  Dao( $connection ); $dao -> insert ( 'value' ); assertInsertedValueMatches( 'value' ); Hard to replace in end to end tests
Dependency lookup
Testing DAOs - dependency lookup $dao   =   new  Dao(); $dao -> insert ( 'value' ); assertInsertedValueMatches( 'value' ); http://xunitpatterns.com/Dependency Lookup.html
DbUnit + Etsy extensions
Test case init class   RemoverDaoTest   extends  DatabaseTestCaseBase { /**   * @return PHPUnit_Extensions_MultipleDatabase_Database[]   */   protected   function   getDatabaseConfigs ()   {   return   array (   $this -> getDbConfigBuilder ()   -> connection ( $this -> getCentralDbConnection ())   -> dataSet ( $this -> createXmlDataSet ( 'init.xml' ))   -> build ()   );   }
Datasets user:  -    id: 1    name: Ingrid <dataset>     <table   name= &quot;user&quot; >         <column> id </column>         <column> name </column>         <row>             <value> 1 </value>             <value> Ingrid </value>         </row>     </table> </dataset> MySQL XML YAML
Assertions public   function   testRemoveNoProblem () {     $remover   =   new  RemoverDao();     $remover -> removeUser ( 1 );     $this -> assertDataSetsEqual (   $this -> createYamlDataSet ( 'empty.yml' ), $this -> getCentralDbConnection () -> createDataSet ( array ( 'user' ))    ); }
Datasets user:  -    id: 1    name: Ingrid    created_at: 2012-01-16 <dataset>     <table   name= &quot;user&quot; >         <column> id </column>         <column> name </column>         <column> created_at </column>         <row>             <value> 1 </value>             <value> Ingrid </value>             <value> 2012-01-16 </value>         </row>     </table> </dataset> MySQL XML YAML
Dataset filter $datasetFilter  =   new  PHPUnit_Extensions_Database_DataSet_DataSetFilter(   $dataset ); $datasetFilter -> addIncludeTables ( array ( 'user' ) ); $datasetFilter -> setExcludeColumnsForTable ( 'user' ,  array ( 'created_at' ) );
Datasets user:  -    id: 1    name: Ingrid    created_at:  ##TIME## <dataset>     <table   name= &quot;user&quot; >         <column> id </column>         <column> name </column>         <column> created_at </column>         <row>             <value> 1 </value>             <value> Ingrid </value>             <value> ##TIME## </value>         </row>     </table> </dataset> MySQL XML YAML
Replacement dataset $replacementDataset   =   new  PHPUnit_Extensions_Database_DataSet_ReplacementDataSet (    $dataset ,  array ( '##TIME##'   =>   TimeService::time ()) );
Implicit setup Common initial state, extended test-by-test Hard to share
Inline setup ,[object Object],[object Object],Still messy to share common datasets with xml or yml Minimal fixture! 
Inline datasets with PHP Value objects + builders Convert to dataset for: ,[object Object],[object Object]
Setup $user    =  UserBuilder :: create () -> build (); $video   =  VideoBuilder :: create ()    -> owner ( $user )    -> private ()    -> build (); TestDataInserter :: create (getCentralDbConnection())    -> add ( 'user' ,  $user )    -> add ( 'video' ,  $video );
Excercise VideoPublisherDao :: create () -> publish ( $video -> id ); Http service DAO HttpClient :: create () -> call ( 'Video::publish' ,  $video -> id );
Verify ,[object Object],[object Object]
Layer crossing tests - where we use it ,[object Object],[object Object],[object Object],[object Object]
The power of layer crossing tests Refactoring (legacy) code Increasing code coverage
There are downsides too We use the back door => risk of  overspecification ,[object Object],[object Object],[object Object]
Concurrent end-to-end black box tests Uses only the front door (public api) Isolation with unique identifiers &  Δ assertions Tests real concurrency Harder to track bugs & intermittent tests http://engineering.imvu.com/2011/01/19/buildbot-and-intermittent-tests/
[email_address] twitter.com/pepov

Mais conteúdo relacionado

Mais procurados

Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
Yi-Huan Chan
 
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
Michelangelo van Dam
 

Mais procurados (20)

QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step TrainingUnit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
 
Core Php Component Presentation
Core Php Component PresentationCore Php Component Presentation
Core Php Component Presentation
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingGetting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
 
Triggers and Stored Procedures
Triggers and Stored ProceduresTriggers and Stored Procedures
Triggers and Stored Procedures
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI FrameworkOwl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
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
 
Test in action week 4
Test in action   week 4Test in action   week 4
Test in action week 4
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
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
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Testing the frontend
Testing the frontendTesting the frontend
Testing the frontend
 
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac..."Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
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
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
 
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 

Semelhante a Testing persistence in PHP with DbUnit

Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
Kiev ALT.NET
 
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
Carles Farré
 
P H P Part I I, By Kian
P H P  Part  I I,  By  KianP H P  Part  I I,  By  Kian
P H P Part I I, By Kian
phelios
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
PrinceGuru MS
 
Liferay Training Struts Portlet
Liferay Training Struts PortletLiferay Training Struts Portlet
Liferay Training Struts Portlet
Saikrishna Basetti
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 

Semelhante a Testing persistence in PHP with DbUnit (20)

Php frameworks
Php frameworksPhp frameworks
Php frameworks
 
Framework
FrameworkFramework
Framework
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
Zend framework 04 - forms
Zend framework 04 - formsZend framework 04 - forms
Zend framework 04 - forms
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
 
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
[DSBW Spring 2009] Unit 07: WebApp Design Patterns & Frameworks (3/3)
 
Intro Open Social and Dashboards
Intro Open Social and DashboardsIntro Open Social and Dashboards
Intro Open Social and Dashboards
 
P H P Part I I, By Kian
P H P  Part  I I,  By  KianP H P  Part  I I,  By  Kian
P H P Part I I, By Kian
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
Liferay Training Struts Portlet
Liferay Training Struts PortletLiferay Training Struts Portlet
Liferay Training Struts Portlet
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 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
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
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
 

Testing persistence in PHP with DbUnit

  • 1. Testing persistence (in PHP) PHPUnit & DbUnit
  • 2. Our story by unit testing classes Started from inside to the outside
  • 3.
  • 4. PHPUnit class TestClass        extends PHPUnit_Framework_TestCase {     public function setUp () {}     public function testMethod () {}     public function tearDown () {} }
  • 5. Problems No integration guarantees Not effective for refactoring legacy code Does not ensure external quality
  • 6. Need for integration tests To ensure external quality from top to bottom
  • 7. Unit testing DAOs with DI and mocks $connection = createMockExpecting(      &quot; INSERT INTO table SET field = 'value' &quot; ); $dao = new Dao( $connection ); $dao -> insert ( 'value' ); Tells nothing about the database interaction
  • 8. Testing DAOs - injected connection $connection = createLocalTestConnection(); $dao = new Dao( $connection ); $dao -> insert ( 'value' ); assertInsertedValueMatches( 'value' ); Hard to replace in end to end tests
  • 10. Testing DAOs - dependency lookup $dao = new Dao(); $dao -> insert ( 'value' ); assertInsertedValueMatches( 'value' ); http://xunitpatterns.com/Dependency Lookup.html
  • 11. DbUnit + Etsy extensions
  • 12. Test case init class RemoverDaoTest extends DatabaseTestCaseBase { /** * @return PHPUnit_Extensions_MultipleDatabase_Database[] */ protected function getDatabaseConfigs () { return array ( $this -> getDbConfigBuilder () -> connection ( $this -> getCentralDbConnection ()) -> dataSet ( $this -> createXmlDataSet ( 'init.xml' )) -> build () ); }
  • 13. Datasets user:  -    id: 1    name: Ingrid <dataset>     <table name= &quot;user&quot; >         <column> id </column>         <column> name </column>         <row>             <value> 1 </value>             <value> Ingrid </value>         </row>     </table> </dataset> MySQL XML YAML
  • 14. Assertions public function testRemoveNoProblem () {     $remover = new RemoverDao();     $remover -> removeUser ( 1 );     $this -> assertDataSetsEqual ( $this -> createYamlDataSet ( 'empty.yml' ), $this -> getCentralDbConnection () -> createDataSet ( array ( 'user' ))    ); }
  • 15. Datasets user:  -    id: 1    name: Ingrid    created_at: 2012-01-16 <dataset>     <table name= &quot;user&quot; >         <column> id </column>         <column> name </column>         <column> created_at </column>         <row>             <value> 1 </value>             <value> Ingrid </value>             <value> 2012-01-16 </value>         </row>     </table> </dataset> MySQL XML YAML
  • 16. Dataset filter $datasetFilter = new PHPUnit_Extensions_Database_DataSet_DataSetFilter( $dataset ); $datasetFilter -> addIncludeTables ( array ( 'user' ) ); $datasetFilter -> setExcludeColumnsForTable ( 'user' , array ( 'created_at' ) );
  • 17. Datasets user:  -    id: 1    name: Ingrid    created_at: ##TIME## <dataset>     <table name= &quot;user&quot; >         <column> id </column>         <column> name </column>         <column> created_at </column>         <row>             <value> 1 </value>             <value> Ingrid </value>             <value> ##TIME## </value>         </row>     </table> </dataset> MySQL XML YAML
  • 18. Replacement dataset $replacementDataset = new PHPUnit_Extensions_Database_DataSet_ReplacementDataSet (   $dataset , array ( '##TIME##' => TimeService::time ()) );
  • 19. Implicit setup Common initial state, extended test-by-test Hard to share
  • 20.
  • 21.
  • 22. Setup $user   = UserBuilder :: create () -> build (); $video = VideoBuilder :: create ()   -> owner ( $user )   -> private ()   -> build (); TestDataInserter :: create (getCentralDbConnection())   -> add ( 'user' , $user )   -> add ( 'video' , $video );
  • 23. Excercise VideoPublisherDao :: create () -> publish ( $video -> id ); Http service DAO HttpClient :: create () -> call ( 'Video::publish' , $video -> id );
  • 24.
  • 25.
  • 26. The power of layer crossing tests Refactoring (legacy) code Increasing code coverage
  • 27.
  • 28. Concurrent end-to-end black box tests Uses only the front door (public api) Isolation with unique identifiers &  Δ assertions Tests real concurrency Harder to track bugs & intermittent tests http://engineering.imvu.com/2011/01/19/buildbot-and-intermittent-tests/