tdd with phpspec2
DESCRIPTION
TRANSCRIPT
TDD with phpspec2
Who I am• Anton Serdyuk
• email/jabber: [email protected]
• skype: serdyuk.anton
• twitter: @anton_serdyuk
• facebook: anton.serdyuk
Overview
Auto-tests forms
• Functional tests (+BDD)
• Integration tests
• Unit tests
Functional tests
• Use full deployed application instance
• Test business expectations
• Use the same UI interactions as real user
Functional tests with phpunit example
BDD (or story BDD)
• Story-driven functional tests
• BDD ⊂ Functional tests
BDD with behat example
Integration tests
• Use integrated parts of applications
• Can use database, filesystem etc.
• Can test API, Doctrine repositories etc.
Integration tests with PHPUnit example
Unit tests
• Use small parts of code
• Can not use database
• Can not use filesystem
• Extremely fast
Consider using appropriate tools for testsphpunit behat phpspec codeception
Functional + + +
Integration + +(sometimes) +
Unit + + +
My personal preference
• behat for functional and API integration tests
• PHPUnit for integration tests
• phpspec for unittest
phpspec basics
Installation
Create testfor class Wow\Hero
Run testsphpspec will create classes for you
Run testsgenerated class Wow\Hero
Run testsRun tests again, now with generated class
Matchers (assertions)Every hero has level
Matchersphpspec will generate code for you
Matchersphpspec will generate code for you
MatchersRed
MatchersGreen
MatchersRefactor
Matchers• Identity (return, be, equal, beEqualTo) - ===
• Comparison (beLike) - ==
• Throw (throw -> during) - exceptions
• Type (beAnInstanceOf etc.) - type
• Custom matchers
• http://www.phpspec.net/cookbook/matchers.html
MatchersUse source code for more matchers
Exception MatchersGenerate
Exception MatchersGenerate
Exception MatchersGenerate
Exception MatchersRed
Exception MatchersGreen
MocksEvery Hero has race and class
MocksGenerate
MocksGenerate
MocksGenerate
MocksRed
MocksGreen
MocksGreen (whoops!)
MocksGreen
MocksRefactor - let() / letgo()
MocksRefactor - let() / letgo()
MocksRefactor
Predictions
PredictionsRed
PredictionsGreen
PredictionsRed
PredictionsGreen
Advanced topics
Nested Object Matchers
Public Property MockSometimes you want to mock public properties
Promises and Predictions Order1) Promises -> 2) Predictions -> 3) Call
Promises and Predictions Order1) Promises -> 2) Predictions -> 3) Call
Promises and Predictions Order1) Promises -> 2) Predictions -> 3) Call
Predictions Argument Wildcarding
Predictions Argument Wildcarding
• Argument::exact($value)
• Argument::type($typeOrClass)
• Argument::which($method, $value)
• Argument::that(callback)
• Argument::any()
• Argument::cetera()
• https://github.com/phpspec/prophecy#arguments-wildcarding
Array MocksGenerate
Array MocksGenerate
Array MocksRed
Array MocksGreen (whoops!)
Array MocksGreen
Get Mock Object
Get Mock Object
Get Mock ObjectGenerate
Get Mock ObjectGenerate (whoops!)
Get Mock ObjectThis is PHP, baby
???
Get Mock ObjectRight way
Best PracticesIMHOs
Do not use TDD in simple CRUD applications (IMHO)
• High cost
• Slow (in terms of development time)
• Zero profit
• Use functional and integration tests instead
Do not mock 3rd party code
• Large complicated tests
• You actually test not how your code works with this library, but how your code works with your understanding of this library
Do not mock 3rd party codeUse interfaces instead of 3rd party dependent code
Consider using appropriate DI library
• symfony/di and Pimple are not well suited for TDD because of large amount of small classes
• you must define rule for every class, which is very boring
• There are some DI containers which will create most objects without explicitly defined rules by just reading constructor arguments type hints through reflection
Consider using appropriate DI library
• zend-di
• Laravel IoC Container - http://laravel.com/docs/ioc
• PHP-DI - http://php-di.org/
phpspec at CI
phpspec junit formatter
Thank you!Questions?