PHPSpec BDD for PHP
Marcello Duarte          @_mdPHPSpec Lead DeveloperHead of Training @Agile guy
What is PHPSpec?
What is PHPSpec? BDD Framework
What is PHPSpec? BDD Framework Created by Pádraic Brady
What is PHPSpec? BDD Framework Created by Pádraic Brady DSL based on RSpec
BDD?Better way to explain TDD
TDD?
TDD?Write a failing test
TDD?       Write a failing testMake it fail for the right reasons
TDD?      Write a failing testMake it fail for the right reasons   Make it pass (just about)
TDD?      Write a failing testMake it fail for the right reasons  Make it pass (just about)            Refactor
Unit TestingXP: test everything that can possibly break
Unit TestingXP: test everything that can possibly break       Unit: vague and structural 1:1
Unit TestingXP: test everything that can possibly break       Unit: vague and structural 1:1       Focus on code not behav...
It’s all in the mind It’s soo simple, it does not need tests
It’s all in the mind It’s soo simple, it does not need tests      I’ve done this millions of times
It’s all in the mind      It’s soo simple, it does not need tests           I’ve done this millions of timesI will write m...
Focus on value
Focus on behaviour
Test
Test
TestSpecify
class CalculatorTest      becomesclass DescribeCalculator
Test Case
Test Case
Test CaseContext
class CalculatorTest extends   SomeTestFramework_TestCase          becomesclass DescribeCalculator extends        PHPSpecC...
Test Method
Test Method
Test Method Example
testAddWithNoArguments()         becomesitReturnsZeroWithNoArguments()
Assert
Assert
AssertExpect
$this->assertEquals(0, $result);         becomes    $result->should->be(0);
InstallingPEAR (soon...)# pear channel-discover pear.phpspec.netAdding Channel "pear.phpspec.net" succeededDiscovery of ch...
Set initial state# StringCalculatorSpec.php<?phpclass DescribeStringCalculator extends PHPSpecContext{    function before(...
PHPSpec DSLclass DescribeStringCalculator extends PHPSpecContext{    ...    function itReturnsZeroWithNoArguments()    {  ...
Lets run our specs$ phpspec StringCalculatorSpec.php -c..Finished in 0.055689 seconds2 examples, 0 failures
Pending examplesfunction itReturnsTheBareNumber(){    $this->pending(Waiting to clarify the spec);}
$ phpspec StringCalculatorSpec.php -c..*Pending:  String Calculator returns the bare number     # Waiting to clarify the s...
Failing examplespublic function itReturnsTheSumOfSpaceSeparatedString(){    $this->calculator->add(4 2)->should->be(6);}//...
$ phpspec StringCalculatorSpec.php -c.*.FPending:  String Calculator returns the bare number     # Waiting to clarify the ...
$result->should->be(0)$result->shouldNot->be(42)
$ phpspec StringCalculatorSpec.php -c.*.FPending:  String Calculator returns the bare number     # Waiting to clarify the ...
Deliberate failpublic function itReturnsTheBareNumber(){    $this->fail(Just because);}
$ phpspec StringCalculatorSpec.php -c.*.FPending:  String Calculator returns the bare number     # Waiting to clarify the ...
Matchers
be($match)         equal($match)       beEqualTo($match)    beAnInstanceOf($match)            beEmpty()            beFalse...
And more matchers...
beInteger()     beLessThan($match)beLessThanOrEqualTo($match)           beNull()          beString()           beTrue()  t...
beInteger()     beLessThan($match)beLessThanOrEqualTo($match)           beNull()          beString()           beTrue()   ...
Predicate Matcher           $cell = $this->spec(new Cell);           $cell->should->beAlive();class Cell{    protected $al...
Predicate Matcher           $newNode = $this->spec(new Node);           $newNode->shouldNot->haveChildren();class Node{   ...
User De ned Matcherclass DescribeRapture extends PHPSpecContext{   ...    function itIsNotTheEndOfTheWorldAsWeKnowIt()    ...
$ phpspec RaptureSpec.php -cEExceptions:  1) Rapture is not the end of the world as we know it     Failure/Error: $this->r...
PHPSpecMatcherdefine(happenToday, function() {    return array (        match => function($rapture) {            return $r...
http://farm5.static.flickr.com/4140/4926597784_4392361eb6_b_d.jpg
PHPSpecMatcherdefine(contain, function($course) {    return array (        match => function($repository) use ($course) { ...
$ phpspec CourseRepositorySpec.php -cFFailures:  1) Course Repository adds new courses     Failure/Error: $this->courses->...
Hooks  before()   after()beforeAll() afterAll()
Mocks
Mocks mock() stub()double()
Stub Example$greeter = stub(Greeter);$greeter->stub(greet)->andReturn(Hello Mocks!);$hello = $this->spec(new HelloWorld($g...
Partial Stub$greeter = mock(Greeter);$greeter ->stub(greet)         ->shouldReceive(Chuck)         ->andReturn(Hello Chuck...
Shortcut$greeter = stub(Greeter, array(greet => Hello World!));$hello = $this->spec(new HelloWorld($greeter));$hello->sayH...
Mocks and hinted typeclass HelloWorld{    public function __construct(Greeter $greeter) // <-- type    {        ...    }}$...
Empty doublesclass HelloWorld{    public function __construct($greeter) // <-- no type    {        ...    }}$greeter = moc...
Counters$greeter ->stub(greet)->andReturn(Hello Chuck!)         ->exactly(42);$greeter ->stub(greet)->andReturn(Hello Chuc...
Coming soon (more counters)$greeter ->stub(greet)->andReturn(Hello Chuck!)         ->atLeast(2);$greeter ->stub(greet)->an...
Coming soon (stub chain)                        Instead of$frontController = double();$dispatcher       = double();$route ...
Coming soon (stub chain)                      You can have$request->stubChain(frontController, dispatcher, route,request);
More to come      CI friendly reports      functional approach           backtrace             fail fast            autoru...
Links http://github.com/phpspec/phpspechttp://github/phpspec/phpspec-mocks        http://www.phpspec.nethttp://dannorth.ne...
Thank you!       Marcello Duarte           @_mdhttp://joind.in/talk/view/3469   is hiring. Come talk to me.
Upcoming SlideShare
Loading in...5
×

PHPSpec BDD for PHP

8,369

Published on

Lightening talk on PHPSpec 1.1.0beta given at the Dutch PHP Conference, 20th May 2011

Published in: Technology
2 Comments
16 Likes
Statistics
Notes
No Downloads
Views
Total Views
8,369
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
97
Comments
2
Likes
16
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • tester hat\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • http://farm5.static.flickr.com/4140/4926597784_4392361eb6_b_d.jpg\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • Differs from normal practice in terms of effort and awareness\n
  • PHPSpec BDD for PHP

    1. 1. PHPSpec BDD for PHP
    2. 2. Marcello Duarte @_mdPHPSpec Lead DeveloperHead of Training @Agile guy
    3. 3. What is PHPSpec?
    4. 4. What is PHPSpec? BDD Framework
    5. 5. What is PHPSpec? BDD Framework Created by Pádraic Brady
    6. 6. What is PHPSpec? BDD Framework Created by Pádraic Brady DSL based on RSpec
    7. 7. BDD?Better way to explain TDD
    8. 8. TDD?
    9. 9. TDD?Write a failing test
    10. 10. TDD? Write a failing testMake it fail for the right reasons
    11. 11. TDD? Write a failing testMake it fail for the right reasons Make it pass (just about)
    12. 12. TDD? Write a failing testMake it fail for the right reasons Make it pass (just about) Refactor
    13. 13. Unit TestingXP: test everything that can possibly break
    14. 14. Unit TestingXP: test everything that can possibly break Unit: vague and structural 1:1
    15. 15. Unit TestingXP: test everything that can possibly break Unit: vague and structural 1:1 Focus on code not behaviour
    16. 16. It’s all in the mind It’s soo simple, it does not need tests
    17. 17. It’s all in the mind It’s soo simple, it does not need tests I’ve done this millions of times
    18. 18. It’s all in the mind It’s soo simple, it does not need tests I’ve done this millions of timesI will write my code rst and test if I have time
    19. 19. Focus on value
    20. 20. Focus on behaviour
    21. 21. Test
    22. 22. Test
    23. 23. TestSpecify
    24. 24. class CalculatorTest becomesclass DescribeCalculator
    25. 25. Test Case
    26. 26. Test Case
    27. 27. Test CaseContext
    28. 28. class CalculatorTest extends SomeTestFramework_TestCase becomesclass DescribeCalculator extends PHPSpecContext
    29. 29. Test Method
    30. 30. Test Method
    31. 31. Test Method Example
    32. 32. testAddWithNoArguments() becomesitReturnsZeroWithNoArguments()
    33. 33. Assert
    34. 34. Assert
    35. 35. AssertExpect
    36. 36. $this->assertEquals(0, $result); becomes $result->should->be(0);
    37. 37. InstallingPEAR (soon...)# pear channel-discover pear.phpspec.netAdding Channel "pear.phpspec.net" succeededDiscovery of channel "pear.phpspec.net" succeeded# pear config-set preferred_state beta# pear install --alldeps phpspec/PHPSpecGITHUB$ git clone git://github.com/phpspec/phpspec.git
    38. 38. Set initial state# StringCalculatorSpec.php<?phpclass DescribeStringCalculator extends PHPSpecContext{ function before() { $this->calculator = $this->spec(new StringCalculator); }}
    39. 39. PHPSpec DSLclass DescribeStringCalculator extends PHPSpecContext{ ... function itReturnsZeroWithNoArguments() { $this->calculator->add()->should->be(0); }}
    40. 40. Lets run our specs$ phpspec StringCalculatorSpec.php -c..Finished in 0.055689 seconds2 examples, 0 failures
    41. 41. Pending examplesfunction itReturnsTheBareNumber(){ $this->pending(Waiting to clarify the spec);}
    42. 42. $ phpspec StringCalculatorSpec.php -c..*Pending: String Calculator returns the bare number # Waiting to clarify the spec # ./spec/StringCalculatorSpec.php:19Finished in 0.056134 seconds2 examples, 0 failures, 1 pending$
    43. 43. Failing examplespublic function itReturnsTheSumOfSpaceSeparatedString(){ $this->calculator->add(4 2)->should->be(6);}// this will fail because it’s not yet implemented
    44. 44. $ phpspec StringCalculatorSpec.php -c.*.FPending: String Calculator returns the bare number # Waiting to clarify the spec # ./spec/StringCalculatorSpec.php:19Failures: 1) String Calculator returns the sum of space separate string expected 6, got NULL (using be()) # .spec/StringCalculatorSpec.php:28Finished in 0.056134 seconds4 examples, 1 failure, 1 pending$
    45. 45. $result->should->be(0)$result->shouldNot->be(42)
    46. 46. $ phpspec StringCalculatorSpec.php -c.*.FPending: String Calculator returns the bare number # Waiting to clarify the spec # ./spec/StringCalculatorSpec.php:19Failures: 1) String Calculator returns the sum of space separate string expected 42, not to be 24 (using be()) # .spec/StringCalculatorSpec.php:28Finished in 0.056134 seconds4 examples, 1 failure, 1 pending$
    47. 47. Deliberate failpublic function itReturnsTheBareNumber(){ $this->fail(Just because);}
    48. 48. $ phpspec StringCalculatorSpec.php -c.*.FPending: String Calculator returns the bare number # Waiting to clarify the spec # ./spec/StringCalculatorSpec.php:19Failures: 1) String Calculator returns the sum of space separate string expected 42, got 0 (using be()) # .spec/StringCalculatorSpec.php:28 2) StringCalculator returns the sum of any white spaceseparated string Failure/Error: Just becauseFinished in 0.056134 seconds4 examples, 1 failure, 1 pending
    49. 49. Matchers
    50. 50. be($match) equal($match) beEqualTo($match) beAnInstanceOf($match) beEmpty() beFalse() beGreaterThan($match)beGreaterThanOrEqualTo($match)
    51. 51. And more matchers...
    52. 52. beInteger() beLessThan($match)beLessThanOrEqualTo($match) beNull() beString() beTrue() throwException($match)
    53. 53. beInteger() beLessThan($match)beLessThanOrEqualTo($match) beNull() beString() beTrue() w throwException($match) ne
    54. 54. Predicate Matcher $cell = $this->spec(new Cell); $cell->should->beAlive();class Cell{ protected $alive = true; public function isAlive() { return $this->alive; } ...}
    55. 55. Predicate Matcher $newNode = $this->spec(new Node); $newNode->shouldNot->haveChildren();class Node{ protected $children = array(); public function hasChildren() { return count($this->children) > 0; } ...}
    56. 56. User De ned Matcherclass DescribeRapture extends PHPSpecContext{ ... function itIsNotTheEndOfTheWorldAsWeKnowIt() { $today = new DateTime(2011-05-20); $this->rapture->setDate($today) $this->rapture->shouldNot->happenToday(); }}
    57. 57. $ phpspec RaptureSpec.php -cEExceptions: 1) Rapture is not the end of the world as we know it Failure/Error: $this->rapture->shouldNot->happenToday(); PHPSpecException: unknown method call # ./RaptureSpec.php:19 # /usr/share/pear/PHPSpec/Runner/Example.php:168Finished in 0.056134 seconds1 examples, 1 exception$
    58. 58. PHPSpecMatcherdefine(happenToday, function() { return array ( match => function($rapture) { return $rapture->happensToday(); }, failure_message_for_should_not => function($rapture) { return sprintf("expected %s not to mean kaput", $rapture->getDate()); } );});class DescribeRapture extends PHPSpecContext{ ... function itIsNotTheEndOfTheWorldAsWeKnowIt() { $today = new DateTime(2011-05-20); $this->rapture->setDate($today) $this->rapture->shouldNot->happenToday(); }}
    59. 59. http://farm5.static.flickr.com/4140/4926597784_4392361eb6_b_d.jpg
    60. 60. PHPSpecMatcherdefine(contain, function($course) { return array ( match => function($repository) use ($course) { return $repository->has($course); }, failure_message_for_should => function($repository) use ($course) { return "expected $course to be in repository"; } );});class DescribeCourseRepository extends PHPSpecContext{ ... function itAddsNewCourses() { $course = new Course("BDD with PHPSpec"); $this->courses->add($course); $this->courses->should->contain(course); }}
    61. 61. $ phpspec CourseRepositorySpec.php -cFFailures: 1) Course Repository adds new courses Failure/Error: $this->courses->should->contain(course); expected BDD with PHPSpec to be in repository # ./CourseRepository.php:19Finished in 0.056134 seconds1 examples, 1 failure$
    62. 62. Hooks before() after()beforeAll() afterAll()
    63. 63. Mocks
    64. 64. Mocks mock() stub()double()
    65. 65. Stub Example$greeter = stub(Greeter);$greeter->stub(greet)->andReturn(Hello Mocks!);$hello = $this->spec(new HelloWorld($greeter));$hello->sayHello()->should->equal(Hello Mocks!);
    66. 66. Partial Stub$greeter = mock(Greeter);$greeter ->stub(greet) ->shouldReceive(Chuck) ->andReturn(Hello Chuck!);$hello = $this->spec(new HelloWorld($greeter));$hello->sayHello()->should->equal(Hello Chuck!);
    67. 67. Shortcut$greeter = stub(Greeter, array(greet => Hello World!));$hello = $this->spec(new HelloWorld($greeter));$hello->sayHello()->should->equal(Hello World!);
    68. 68. Mocks and hinted typeclass HelloWorld{ public function __construct(Greeter $greeter) // <-- type { ... }}$greeter = mock(Greeter); // <-- we are covered
    69. 69. Empty doublesclass HelloWorld{ public function __construct($greeter) // <-- no type { ... }}$greeter = mock(); // <-- no need for types
    70. 70. Counters$greeter ->stub(greet)->andReturn(Hello Chuck!) ->exactly(42);$greeter ->stub(greet)->andReturn(Hello Chuck!) ->never();
    71. 71. Coming soon (more counters)$greeter ->stub(greet)->andReturn(Hello Chuck!) ->atLeast(2);$greeter ->stub(greet)->andReturn(Hello Chuck!) ->atMost(5);$greeter ->stub(greet)->andReturn(Hello Chuck!) ->between(2..5);
    72. 72. Coming soon (stub chain) Instead of$frontController = double();$dispatcher = double();$route = double();$request = double();$request->stub(frontController) ->andReturn($frontController);$frontController->stub(dispatcher)->andReturn($dispatcher);$dispatcher->stub(route)->andReturn($route);$route->stub(request)->andReturn($request);
    73. 73. Coming soon (stub chain) You can have$request->stubChain(frontController, dispatcher, route,request);
    74. 74. More to come CI friendly reports functional approach backtrace fail fast autorun run single examplesintegration with ZF and Kohana
    75. 75. Links http://github.com/phpspec/phpspechttp://github/phpspec/phpspec-mocks http://www.phpspec.nethttp://dannorth.net/introducing-bdd http://twitter.com/_md http://twitter.com/phpspec
    76. 76. Thank you! Marcello Duarte @_mdhttp://joind.in/talk/view/3469 is hiring. Come talk to me.
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×