Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

PHPSpec BDD for PHP

10.235 visualizaciones

Publicado el

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

Publicado en: Tecnología

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.

×