TDD with phpspec2
Who I am
• Anton Serdyuk
• email/jabber: anton.serdyuk@gmail.com
• 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 tests
phpunit 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 test
for class WowHero
Run tests
phpspec will create classes for you
Run tests
generated class WowHero
Run tests
Run tests again, now with generated class
Matchers (assertions)
Every hero has level
Matchers
phpspec will generate code for you
Matchers
phpspec will generate code for you
Matchers
Red
Matchers
Green
Matchers
Refactor
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
Matchers
Use source code for more matchers
Exception Matchers
Generate
Exception Matchers
Generate
Exception Matchers
Generate
Exception Matchers
Red
Exception Matchers
Green
Mocks
Every Hero has race and class
Mocks
Generate
Mocks
Generate
Mocks
Generate
Mocks
Red
Mocks
Green
Mocks
Green (whoops!)
Mocks
Green
Mocks
Refactor - let() / letgo()
Mocks
Refactor - let() / letgo()
Mocks
Refactor
Predictions
Predictions
Red
Predictions
Green
Predictions
Red
Predictions
Green
Advanced topics
Nested Object Matchers
Public Property Mock
Sometimes you want to mock public properties
Promises and Predictions Order
1) Promises -> 2) Predictions -> 3) Call
Promises and Predictions Order
1) Promises -> 2) Predictions -> 3) Call
Promises and Predictions Order
1) 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 Mocks
Generate
Array Mocks
Generate
Array Mocks
Red
Array Mocks
Green (whoops!)
Array Mocks
Green
Get Mock Object
Get Mock Object
Get Mock Object
Generate
Get Mock Object
Generate (whoops!)
Get Mock Object
This is PHP, baby
???
Get Mock Object
Right way
Best Practices
IMHOs
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 code
Use 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?

TDD with phpspec2