Behavioural Driven Development in Zf2

2,023
-1

Published on

A quick introduction on how to setup a zf2 project using Behat and Phpspec.

Published in: Technology

Behavioural Driven Development in Zf2

  1. 1. Behavior-Driven Development with Zend Framework 2 Zend Framework Day – Turin, Italy – 07/02/2014
  2. 2. DAVID CONTAVALLI @mauipipe 2
  3. 3. CLEAN CODE ADEPT BDD FANATIC 3
  4. 4. CLEAN CODE ADEPT BDD FANATIC 4
  5. 5. WHAT IS BDD?
  6. 6. TDD Evolution 6
  7. 7. SAME RULES 1. 7 You are not allowed to write any production code unless it is to make a failing unit test pass.
  8. 8. SAME RULES 1. 2. 8 You are not allowed to write any production code unless it is to make a failing unit test pass. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  9. 9. SAME RULES 1. 2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures. 3. 9 You are not allowed to write any production code unless it is to make a failing unit test pass. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
  10. 10. WHAT’S THE DIFFERENCE?
  11. 11. TDD STARTS FROM COMPONENTS
  12. 12. CREATE THE TEST private $calculator; function setUp(){ $this->calculator = new Calculator(); } function testSumTwoPositive(){ $expectedResult = 8; $result = $this->calculator(6,2); assertEquals($expectedResult,$result); } 12
  13. 13. 13
  14. 14. WRITE QUICK, TEST VALIDATING CODE class Calculator{ public function sum($num1, $num2){ return 8; } } 14
  15. 15. 15
  16. 16. REFACTOR class Calculator{ public function sum($num1, $num2){ $sum = $num1 + $num2; return $sum; } } 16
  17. 17. 17
  18. 18. BDD STARTS FROM AN EXAMPLE
  19. 19. SPECIFICATION BY EXAMPLE Scenario: Add two number Given I fill number1 field with 2 And I fill number2 field with 6 When I press Add button Then the result should be 8 19
  20. 20. A COMMON LANGUAGE STAKEHOLDER 20
  21. 21. A COMMON LANGUAGE DEVELOPER STAKEHOLDER 21
  22. 22. A COMMON LANGUAGE DEVELOPER STAKEHOLDER 22 USER
  23. 23. LIVING DOCUMENTATION
  24. 24. HOW IS STORY CODE RELATED?
  25. 25. GHERKIN Scenario: Add two number Given I fill number1 field with 2 And I fill number2 field with 6 When I press Add button Then the result should be 8 25
  26. 26. Interpreted in many languages 26
  27. 27. GHERKIN 27
  28. 28. GHERKIN 28
  29. 29. WHAT IS BEHAT?
  30. 30. Scenario: Add two numbers Given I fill number1 field with value of 2 TRANSLATE /** * @Given /^I fill ([^’’]*) with (d+)$/ **/ public function iFieldFieldWith($number, $fieldName) { throw new PendingException(); } 31
  31. 31. EXECUTION 32
  32. 32. USERS WILL NOT READ STORIES
  33. 33. THEY WILL USE AN UI
  34. 34. BROWSER
  35. 35. HOW TO TEST BROWSER WITH BEHAT? 36
  36. 36. HERE IT COMES, MINK!
  37. 37. GHERKIN + 38
  38. 38. Web Acceptance Test GOUTTE • Headless Browser • No Javascript • Really fast 39
  39. 39. Web Acceptance Test GOUTTE • Headless Browser • No Javascript • Really fast 40 SELENIUM • Can test Javascript • Really slow • Use Firefox as emulator
  40. 40. Web Acceptance Test GOUTTE • Headless Browser • No Javascript • Really fast 41 SELENIUM • Can test Javascript • Really slow • Use Firefox as emulator Zombie.js • Can test Javascript • Medium • Use Firefox as emulator
  41. 41. Web Acceptance Test GOUTTE • Headless Browser • No Javascript • Really fast 42 SELENIUM • Can test Javascript • Really slow • Use Firefox as emulator Zombie.js • Can test Javascript • Medium • Use Firefox as emulator SAHI • Can test Javascript • slow • Emulate every Browser
  42. 42. Scenario: Add two numbers Given I fill number1 field with 2 And I fill number2 field with 6 When I press Add button Then the result should be 8 /** * @When /^I press ‘’(/[^’’]*)’’ button$/ **/ public function iPressButton($buttonName) { $this->pressButton($buttonName); } 43
  43. 43. How to install.... + 44
  44. 44. "require-dev " :{ ......... "behat/behat" : "2.4.*@stable", "behat/mink": "1.5.0", "behat/mink-extension":"*", "behat/mink-browserkit-driver":"dev-master", "behat/mink-goutte-driver":"*", "phpspec/phpspec":" 2.0.*@dev" } 45
  45. 45. Differs from documentation because there is a fix for ZF2 multicheckbox selection "require-dev " :{ ......... "behat/behat" : "2.4.*@stable", "behat/mink": "1.5.0", "behat/mink-extension":"*", "behat/mink-browserkit-driver":"dev-master", "behat/mink-goutte-driver":"*", "phpspec/phpspec":" 2.0.*@dev" } 46
  46. 46. Mink Setup behat.yml default : extensions : BehatMinkExtensionExtension : base_url : 'http://example.com' goutte : ~ 47
  47. 47. + + 48
  48. 48. Static method private static app; /** * @BeforeSuite **/ public static function initializeZf(){ If(self::$zendApp === null){ $path = __DIR__ .’/../../config/application.config.php’; self::app = ZendMvcApplication::init(require $path); } } 49
  49. 49. ZF2 EXTENSION
  50. 50. "require-dev":{ ................ "mvlabs/zf2behat-extension":"dev-master" }, 51
  51. 51. Zf2 Behat Extension behat.yml default : extensions : MvLabsZf2ExtensionZf2Extension : config : config/application.config.php module : 52
  52. 52. Zf2 Behat Extension run from console bin/behat --init ‘’module name’’ 53
  53. 53. Feature Context Implements Zf2AwareContextInterface class FeatureContext extends MinkContext implements Zf2AwareContextInterface{ private $zf2MvcApplication; ......... public function setZf2App(Application $zf2MvcApplication) { $this->zf2MvcApplication = $zf2MvcApplication; } } 54
  54. 54. WE STILL NEED TO TEST OUR COMPONENTS
  55. 55. GHERKIN + 56
  56. 56. WHY PHPSPEC? 57
  57. 57. BDD BASED ON BEHAVIOUR DESCRIPTION Robert C. Martin
  58. 58. PHPUnit focus on testing code private $calculator; function setUp(){ $this->calculator = new Calculator(); } function testSumTwoPositive(){ $expectedResult = 8; $result = $this->calculator(6,2); assertEquals($expectedResult,$result); } 59
  59. 59. PHPSpec focus on code behavior function let(){ $this->shouldBeConstructed(); } function it_sum_two_positive_number(){ $this->sum(2,6)->shouldReturn(8); } 60
  60. 60. Subject under Specification "It’s this unexisting object, on which you’re calling unexisting methods and assuming future outcomes. Most important thing? There could be only one SUS in specification" Kostantin Kudryashov 61
  61. 61. Developer Tool Vs Testing Framework 62
  62. 62. Autogenerates classes & methods bin/phpspec desc ‘’ApplicationControllerIndexController’’ 63
  63. 63. PROMOTES CLEAN CODE
  64. 64. Demeter Law's Violation function let(){ $this->shouldBeConstructed(); } function it_sum_two_positive_number(){ $this->getPlayer()->getSword()->shouldBeInstanceOf(‘Sword’); } 65
  65. 65. Impossible function let(){ $this->shouldBeConstructed(); } function it_sum_two_positive_number(){ $this->getPlayer()->getSword()->shouldBeInstanceOf(‘Sword’); } 66
  66. 66. Add PHPSpec to Zf2 + 67
  67. 67. "require-dev":{ ........... "phpspec/phpspec" : "2.0.*@dev" }, "config": { "bin-dir": "bin/" }, "autoload": { "psr-0" { "Application" : " module/Application/src" } } 68
  68. 68. Add a single module ’’require-dev’’:{ "require-dev":{ ........... ... "phpspec/phpspec" : "2.0.*@dev" "phpspec/phpspec":" 2.0.*@dev" }, }, "config": { "config": { "bin-dir": "bin/" "bin-dir": "bin« }, }, "autoload": { { "autoload": "psr-0" { { "psr-0": "Application" : " module/Application/src" "Application": "module/Application/src" } } }} 69
  69. 69. Add more modules "require-dev":{ ........... "phpspec/phpspec" : "2.0.*@dev" }, "config": { "bin-dir": "bin/" }, "autoload": { "psr-0" { "Application" : " module/Application/src", "Calculator" : "module/Calculator/src" } } 70
  70. 70. Create phpspec.yml in project root formatter.name : progresssuites Application: namespace : Application spec_prefix : Spec src_path : 'module/Application/src/' spec_path : 'module/Application/' ModuleDemo: namespace : ModuleDemo spec_prefix : Spec src_path : 'module/ModuleDemo/src/' spec_path : 'module/ModuleDemo/' 71
  71. 71. What to test with PHPSpec? 72
  72. 72. What to test with PHPSpec? 1.Model Logic 73
  73. 73. What to test with PHPSpec? 1.Model Logic 2.Factories 74
  74. 74. What to test with PHPSpec? 1.Model Logic 2.Factories 3.Validation 75
  75. 75. Behat bad practices 1. Verbose Stories 2. Using Mink to test REST calls 3. Testing every possible usages combination 4. Fixture loading within Context 76
  76. 76. WHY TESTING?
  77. 77. IT’S A TREND
  78. 78. RELAX
  79. 79. SOMEONE WILL READ YOUR CODE
  80. 80. IT COULD BE YOU SOME DAY
  81. 81. YOUR COLLEAGUES
  82. 82. OR 84
  83. 83. A VIOLENT PSYCHOPATH WHO KNOWS WHERE YOU LIVE
  84. 84. Thank you for your attention David Contavalli @mauipipe
  85. 85. QUESTIONS?
  86. 86. @mauipipe mauipipe@gmail.com
  87. 87. Some readings 90
  88. 88. Credits https://www.flickr.com/photos/42788859@N00/318947873 https://www.flickr.com/photos/79811974@N08/8895959339/ https://www.flickr.com/photos/wingedwolf/5471047557/ https://www.flickr.com/photos/21112928@N07/2922128673/ https://www.flickr.com/photos/23408922@N07/8220573257/ https://www.flickr.com/photos/11956371@N07/4146284063/ http://www.flickr.com/photos/chemicalbrother/2540855983/ http://www.flickr.com/photos/slworking/5757370044/ http://www.flickr.com/photos/ter-burg/5807937726/ http://www.flickr.com/photos/thyagohills/5023536434/ http://www.flickr.com/photos/jeremybrooks/2175042537/ http://www.flickr.com/photos/bowmanlibrary/941844481/ http://www.flickr.com/photos/webhamster/2476756607/ http://www.flickr.com/photos/nebirdsplus/5835963068/ http://www.flickr.com/photos/mistaboos/4348381987/ http://www.flickr.com/photos/moofbong/4207382992/ http://www.flickr.com/photos/ryanh/43936630/ http://www.flickr.com/photos/nathangibbs/98592171/ http://www.flickr.com/photos/71894657@N00/2553948289/ http://www.flickr.com/photos/ahia/3168219760/ http://www.flickr.com/photos/smileham/3559228586/ http://www.flickr.com/photos/kk/3834592792/ http://www.flickr.com/photos/enoughproject/5776533975/ http://www.flickr.com/photos/_flood_/8067625282/ http://www.flickr.com/photos/drooo/3114233333/ http://www.flickr.com/photos/84143785@N00/3559757811 91
  89. 89. David Contavalli @mauipipe

×