Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Learn to love testing an agile journey into Behat, PHPSpec and Magento

James Cowie
September 21, 2015

Learn to love testing an agile journey into Behat, PHPSpec and Magento

We all hear that we should be testing our code, but Magento is hard to test, clients don't pay for testing and its a new skill we need to adopt. By looking at testing as an onion we can add value with each layer of the onion skin. During this talk we will look at what is involved in starting to apply testing best practices using Behat and PHPSpec and how they can offer value to the business with User Stories and intertwine with an Agile process. By the end of the talk you will leave feeling ready to install Behat and PHPSpec and start to think about testing as value that can be added before we write code using Given, When and Then to talk to all parties of the business about what is going to happen. We will wrap up with making these stories executable and repeatable using selenium and Behat with some PHPSpec used to write unit tests.

James Cowie

September 21, 2015
Tweet

More Decks by James Cowie

Other Decks in Programming

Transcript

  1. 8

  2. 19 19 the solution dont test simple things prototypes dont

    need tests only test your application
  3. 25 gherkin given then when I am looking to have

    an awesome magento time I attend Meet magento NY 2015 I should have a great time
  4. 27 imperative given I am on a configurable product page

    when I click “.size” And set the value to be “small” And I click “.qty” and I set the value to be “1” when I click “.submit” Then I should see that “.topcart > .qty” is visible
  5. 28 imperative given I am on a configurable product page

    when I click “.size” And set the value to be “small” And I click “.qty” and I set the value to be “1” when I click “.submit” Then I should see that “.topcart > .qty” is visible
  6. 29 imperative - improved given I am on a configurable

    product page When I select the small t-shirt size And I select that I only want to buy 1 When I click submit Then I should see that item in the top cart
  7. 30 declerative given I am on a configurable product page

    when i add a single small t-shirt to my basket then I should see this item in the top cart
  8. 33

  9. 35 { "require-dev": { "behat/behat": "~3", "behat/mink": "~1.6.0", "behat/mink-extension": "~2.0.0",

    "behat/mink-goutte-driver": "~1.1.0", "behat/mink-selenium2-driver": "*", "peridot-php/webdriver-manager": “*" },"config": { "bin-dir": "bin/" } }
  10. 36 { "require-dev": { "behat/behat": "~3", "behat/mink": "~1.6.0", "behat/mink-extension": "~2.0.0",

    "behat/mink-goutte-driver": "~1.1.0", "behat/mink-selenium2-driver": "*", "peridot-php/webdriver-manager": “*" },"config": { "bin-dir": "bin/" } }
  11. 37 { "require-dev": { "behat/behat": "~3", "behat/mink": "~1.6.0", "behat/mink-extension": "~2.0.0",

    "behat/mink-goutte-driver": "~1.1.0", "behat/mink-selenium2-driver": "*", "peridot-php/webdriver-manager": “*" },"config": { "bin-dir": "bin/" } }
  12. 38 { "require-dev": { "behat/behat": "~3", "behat/mink": "~1.6.0", "behat/mink-extension": "~2.0.0",

    "behat/mink-goutte-driver": "~1.1.0", "behat/mink-selenium2-driver": "*", "peridot-php/webdriver-manager": “*" },"config": { "bin-dir": "bin/" } }
  13. 45 +d features - place your *.feature files here +d

    features/bootstrap - place your context classes here +f features/bootstrap/FeatureContext.php - place your definitions, transformations and hooks here
  14. 46 Dear Agency, Please can you add a section on

    the product details page that allows a visitor to share the product via twitter. This needs to be configurable via the admin so I can enable or disable it should also allow me to add a message that is sent via the tweet. Thanks Your loving customer
  15. 48 Feature: Share via twitter In order to share products

    I like with my followers As a visitor of the site I need to be able to quickly share the product via twitter
  16. 49 Feature: Share via twitter In order to share products

    I like with my followers As a visitor of the site I need to be able to quickly share the product via twitter Scenario: Admin can configure a product to be shared Given I am logged into the admin as "admin" with "password123" And I enabled social-share for "product-1" When I save the product Then I should see a success message
  17. 50 Feature: Share via twitter In order to share products

    I like with my followers As a visitor of the site I need to be able to quickly share the product via twitter Scenario: Admin can configure a product to be shared Given I am logged into the admin as "admin" with "password123" And I enabled social-share for "product-1" When I save the product Then I should see a success message Scenario: Visitor can share a product via twitter Given "product-1" is enabled for social-share When I visit the product details page Then I should see that I can share the product via twitter
  18. 52 Feature: Share via twitter In order to share products

    I like with my followers As a visitor of the site I need to be able to quickly share the product via twitter Scenario: Admin can configure a product to be shared Given I am logged into the admin as "admin" with "password123" And I enabled social-share for "product-1" When I save the product Then I should see a success message Scenario: Visitor can share a product via twitter Given "product-1" is enabled for social-share When I visit the product details page Then I should see that I can share the product via twitter 2 scenarios (2 undefined) 7 steps (7 undefined) 0m0.05s (11.13Mb)
  19. 53 --- FeatureContext has missing steps. Define them with these

    snippets: /** * @Given I am logged into the admin as :arg1 with :arg2 */ public function iAmLoggedIntoTheAdminAsWith($arg1, $arg2) { throw new PendingException(); } /** * @Given I enabled social-share for :arg1 */ public function iEnabledSocialShareFor($arg1) { throw new PendingException(); } …
  20. 55 u features/bootstrap/FeatureContext.php - `I am logged into the admin

    as "admin" with "password123"` definition added u features/bootstrap/FeatureContext.php - `I enabled social-share for "product-1"` definition added u features/bootstrap/FeatureContext.php - `I save the product` definition added u features/bootstrap/FeatureContext.php - `I should see a success message` definition added u features/bootstrap/FeatureContext.php - `"product-1" is enabled for social-share` definition added u features/bootstrap/FeatureContext.php - `I visit the product details page` definition added u features/bootstrap/FeatureContext.php - `I should see that I can share the product via twitter` definition added
  21. 56 half time installed and configured behat / mink Used

    gherkin to write a scenario code generation
  22. 57 <?php use Behat\MinkExtension\Context\RawMinkContext; /** * Defines application features from

    the specific context. */ class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext { /** * @Given I am logged into the admin as :arg1 with :arg2 */ public function iAmLoggedIntoTheAdminAsWith($arg1, $arg2) { throw new PendingException(); } }
  23. 58 <?php class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext {

    /** * @Given I am logged into the admin as :username with :password */ public function iAmLoggedIntoTheAdminAsWith($username, $password) { $this->visitPath('/admin'); } }
  24. 59 <?php class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext {

    /** * @Given I am logged into the admin as :username with :password */ public function iAmLoggedIntoTheAdminAsWith($username, $password) { $this->visitPath(‘/admin'); $this->getSession()->getPage()->fillField('username', $username); $this->getSession()->getPage()->fillField('password', $password); } }
  25. 60 <?php class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext {

    /** * @Given I am logged into the admin as :username with :password */ public function iAmLoggedIntoTheAdminAsWith($username, $password) { $this->visitPath(‘/admin'); $this->getSession()->getPage()->fillField('username', $username); $this->getSession()->getPage()->fillField('password', $password); $this->getSession()->getPage()->find('css', '.submit')->click(); } }
  26. 62 <?php /** * Defines application features from the specific

    context. */ class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext { /** * @Then I should see a success message */ public function iShouldSeeASuccessMessage() { $message = $this->getSession()->getPage()->find(‘success-message'); } }
  27. 63 <?php /** * Defines application features from the specific

    context. */ class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext { /** * @Then I should see a success message */ public function iShouldSeeASuccessMessage() { $message = $this->getSession()->getPage()->find('success-message'); expect($message->getHtml())->notToBe(); } }
  28. 65 One of the most important parts in the web

    is a browser. Browser is the window through which web users interact with web applications and other users. Users are always talking with web applications through browsers. So, in order to test that our web application behaves correctly, we need a way to simulate this interaction between the browser and the web application in our tests. We need a Mink. http://mink.behat.org/en/latest/ ” “
  29. 66

  30. 72

  31. 76 { "autoload": { "psr-0": { "": [ "public/app", "public/app/code/local",

    "public/app/code/community", "public/app/code/core", "public/lib" ] } } }
  32. 80

  33. 81 MeetMagento_NY_Block_Social 10 - it is initializable class MeetMagento_NY_Block_Social does

    not exist. 100% 1 1 specs 1 example (1 broken) 20ms Do you want me to create `MeetMagento_NY_Block_Social` for you? [Y/n] Y Magento block MeetMagento_NY_Block_Social created in '/Users/jamescowie/ Dropbox/Presentations/Magento/Meet Magento NY/code/magento/app/code/local/ MeetMagento/NY/Block/Social.php'.
  34. 86