SlideShare a Scribd company logo
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 Design for testability (SOLID) Use the front door first One condition per test 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 Define only the tables being used in common setup Insert all the necessary data inline in the test method Still messy to share common datasets with xml or yml Minimal fixture! 
Inline datasets with PHP Value objects + builders Convert to dataset for: inserting into database using in assertions
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 assertDataSetsEqual(    $this -> createDataSet ( 'video' ,  $video ),    $this -> getCentralDbConnection () -> createDataSet ( array ( 'video' )) );
Layer crossing tests - where we use it Http services Daemons Cron jobs Ajax calls
The power of layer crossing tests Refactoring (legacy) code Increasing code coverage
There are downsides too We use the back door => risk of  overspecification Empty initial state  hides concurrency problems parallel testing more difficult
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
Ad

Recommended

Testing database content with DBUnit. My experience.
Testing database content with DBUnit. My experience.
Serhii Kartashov
 
Devoxx 15 equals hashcode
Devoxx 15 equals hashcode
bleporini
 
Advanced PHPUnit Testing
Advanced PHPUnit Testing
Mike Lively
 
Test driven development_for_php
Test driven development_for_php
Lean Teams Consultancy
 
Unit Testing in SilverStripe
Unit Testing in SilverStripe
Ingo Schommer
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
Tricode (part of Dept)
 
Phpunit testing
Phpunit testing
Nikunj Bhatnagar
 
PL/SQL Unit Testing Can Be Fun!
PL/SQL Unit Testing Can Be Fun!
Raimonds Simanovskis
 
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
GeeksLab Odessa
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
Core Php Component Presentation
Core Php Component Presentation
John Coonen
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
Mark Rickerby
 
Triggers and Stored Procedures
Triggers and Stored Procedures
Tharindu Weerasinghe
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
Odoo
 
Introduction to Django
Introduction to Django
colinkingswood
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
Michelangelo van Dam
 
Test in action week 4
Test in action week 4
Yi-Huan Chan
 
Having Fun with Play
Having Fun with Play
Clinton Dreisbach
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
Michelangelo van Dam
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
Paweł Michalik
 
Testing the frontend
Testing the frontend
Heiko Hardt
 
"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...
Fwdays
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
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 Engine
River of Talent
 
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.
Graham Dumpleton
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Php frameworks
Php frameworks
Anil Kumar Panigrahi
 
Framework
Framework
Nguyen Linh
 

More Related Content

What's hot (20)

QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
GeeksLab Odessa
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
Core Php Component Presentation
Core Php Component Presentation
John Coonen
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
Mark Rickerby
 
Triggers and Stored Procedures
Triggers and Stored Procedures
Tharindu Weerasinghe
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
Odoo
 
Introduction to Django
Introduction to Django
colinkingswood
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
Michelangelo van Dam
 
Test in action week 4
Test in action week 4
Yi-Huan Chan
 
Having Fun with Play
Having Fun with Play
Clinton Dreisbach
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
Michelangelo van Dam
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
Paweł Michalik
 
Testing the frontend
Testing the frontend
Heiko Hardt
 
"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...
Fwdays
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
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 Engine
River of Talent
 
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.
Graham Dumpleton
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
QA Lab: тестирование ПО. Яков Крамаренко: "KISS Automation"
GeeksLab Odessa
 
Unit Testng with PHP Unit - A Step by Step Training
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
Core Php Component Presentation
Core Php Component Presentation
John Coonen
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
Mark Rickerby
 
Owl: The New Odoo UI Framework
Owl: The New Odoo UI Framework
Odoo
 
Introduction to Django
Introduction to Django
colinkingswood
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
Michelangelo van Dam
 
Test in action week 4
Test in action week 4
Yi-Huan Chan
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
Michelangelo van Dam
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
Paweł Michalik
 
Testing the frontend
Testing the frontend
Heiko Hardt
 
"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...
Fwdays
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
Michelangelo van Dam
 
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 Engine
River of Talent
 
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.
Graham Dumpleton
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
Michelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 

Similar to Testing persistence in PHP with DbUnit (20)

Php frameworks
Php frameworks
Anil Kumar Panigrahi
 
Framework
Framework
Nguyen Linh
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
olegmmiller
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
ipolevoy
 
Web Scraping with PHP
Web Scraping with PHP
Matthew Turland
 
Zend framework 04 - forms
Zend framework 04 - forms
Tricode (part of Dept)
 
Unit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Micro-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)
Carles Farré
 
Intro Open Social and Dashboards
Intro Open Social and Dashboards
Atlassian
 
P H P Part I I, By Kian
P H P Part I I, By Kian
phelios
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
PrinceGuru MS
 
Web Scraping with PHP
Web Scraping with PHP
Matthew Turland
 
PHP Unit Testing
PHP Unit Testing
Tagged Social
 
Liferay Training Struts Portlet
Liferay Training Struts Portlet
Saikrishna Basetti
 
Система рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 
QA for PHP projects
QA for PHP projects
Michelangelo van Dam
 
Extend sdk
Extend sdk
Harsha Nagaraj
 
Create a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
olegmmiller
 
ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
ipolevoy
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Micro-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)
Carles Farré
 
Intro Open Social and Dashboards
Intro Open Social and Dashboards
Atlassian
 
P H P Part I I, By Kian
P H P Part I I, By Kian
phelios
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
PrinceGuru MS
 
Liferay Training Struts Portlet
Liferay Training Struts Portlet
Saikrishna Basetti
 
Система рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 
Ad

Recently uploaded (20)

" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
Fwdays
 
From Manual to Auto Searching- FME in the Driver's Seat
From Manual to Auto Searching- FME in the Driver's Seat
Safe Software
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
The Future of Technology: 2025-2125 by Saikat Basu.pdf
The Future of Technology: 2025-2125 by Saikat Basu.pdf
Saikat Basu
 
Daily Lesson Log MATATAG ICT TEchnology 8
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
Quantum AI: Where Impossible Becomes Probable
Quantum AI: Where Impossible Becomes Probable
Saikat Basu
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Safe Software
 
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
Safe Software
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
Fwdays
 
From Manual to Auto Searching- FME in the Driver's Seat
From Manual to Auto Searching- FME in the Driver's Seat
Safe Software
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
Tech-ASan: Two-stage check for Address Sanitizer - Yixuan Cao.pdf
caoyixuan2019
 
The Future of Technology: 2025-2125 by Saikat Basu.pdf
The Future of Technology: 2025-2125 by Saikat Basu.pdf
Saikat Basu
 
Daily Lesson Log MATATAG ICT TEchnology 8
Daily Lesson Log MATATAG ICT TEchnology 8
LOIDAALMAZAN3
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
10 Key Challenges for AI within the EU Data Protection Framework.pdf
10 Key Challenges for AI within the EU Data Protection Framework.pdf
Priyanka Aash
 
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Quantum AI Discoveries: Fractal Patterns Consciousness and Cyclical Universes
Saikat Basu
 
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
Salesforce Summer '25 Release Frenchgathering.pptx.pdf
yosra Saidani
 
Quantum AI: Where Impossible Becomes Probable
Quantum AI: Where Impossible Becomes Probable
Saikat Basu
 
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC and Open Hackathons Monthly Highlights June 2025
OpenACC
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Enhance GitHub Copilot using MCP - Enterprise version.pdf
Nilesh Gule
 
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Using the SQLExecutor for Data Quality Management: aka One man's love for the...
Safe Software
 
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
AI Agents and FME: A How-to Guide on Generating Synthetic Metadata
Safe Software
 
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Coordinated Disclosure for ML - What's Different and What's the Same.pdf
Priyanka Aash
 
Ad

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. Tools and principles Using PHPUnit with Mock objects  to isolate the SUT Design for testability (SOLID) Use the front door first One condition per test http://xunitpatterns.com/Principles of Test Automation.html http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
  • 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. Inline setup Define only the tables being used in common setup Insert all the necessary data inline in the test method Still messy to share common datasets with xml or yml Minimal fixture! 
  • 21. Inline datasets with PHP Value objects + builders Convert to dataset for: inserting into database using in assertions
  • 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. Verify assertDataSetsEqual(   $this -> createDataSet ( 'video' , $video ),   $this -> getCentralDbConnection () -> createDataSet ( array ( 'video' )) );
  • 25. Layer crossing tests - where we use it Http services Daemons Cron jobs Ajax calls
  • 26. The power of layer crossing tests Refactoring (legacy) code Increasing code coverage
  • 27. There are downsides too We use the back door => risk of  overspecification Empty initial state  hides concurrency problems parallel testing more difficult
  • 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/