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

Outside in BDD

Outside in BDD

How to develop software that matters using outside in behaviour driven developmend

James Cowie

January 09, 2015
Tweet

More Decks by James Cowie

Other Decks in Programming

Transcript

  1. Who am I • James Cowie • Software Engineer •

    Session Digital • BDD Practitioner • @jcowie • github.com/jamescowie
  2. Introducing BDD “Software development practice that emphasises development through an

    example-based conversations with users and stakeholders of the system.“
  3. Evolution / Process of BDD • Inspired by eXtreme programming

    and Agile • Example workshops • User stories • Story mapping
  4. • Evolved from Test-first development • Common language • Behaviour

    • Discovering and delivery what matters most first What is BDD
  5. The requirement Hello Development Agency, We have found that lots

    of our customers tweet about the products they are buying from our website. Can you include a twitter widget on the productpage and we can configure a message via the admin section ? We think this will encourage more people to share the products on the timeline and increase our sales. Hope this is ok. Client
  6. Setting up the tools { "require": { "php": ">=5.4.0" },

    "require-dev": { "magetest/magento-phpspec-extension": "2.1.*", "magetest/magento-behat-extension": "dev-feature/Behat3", "bossa/phpspec2-expect": "dev-master" }, "config": { "bin-dir": "bin" }, "autoload": { "psr-0": { "MageTest\\PhpSpec\\MagentoExtension": "src", "": [ "public/app/code/local", "public/app/code/community", "public/app/code/core", "public/app", "public/lib" ], "Mage" : "public/app/code/core" } } }
  7. Behat.yml default: suites: default: paths: features: features/visitor contexts: - VisitorBrowsingContext

    extensions: MageTest\MagentoExtension\Extension: ~ base_url: http://magento.local/ Conversation
  8. What makes a story Given When Then Context: The context

    for this specific scenario, for example Given the customer is logged in. Event: What the feature should be doing, for example When the customer clicks add to cart. Outcome: The expected result from a given context and event. Example: “Then the product should be added to the shopping cart.”
  9. Narrative Feature: Visitors can share via twitter In order to

    allow visitors to share our products As a site owner I need to offer a way to share via twitter my products Scenario: Visitor can share a product via twitter Given I have twitter enabled with a username When I view a product page Then I should see a twitter block with my message configured
  10. Running Behat ➜ Magento behat Feature: Any customer to the

    site will see a twitter widget on the product page In order to allow visitors to share our products As a site owner I need to offer a way to share via twitter my products Scenario: Visitor can share a product via twitter Given I have twitter enabled with a username TODO: write pending definition When I view a product page Then I should see a twitter block with my message configured # 1 scenario (1 pending) 3 steps (1 pending, 2 skipped) 0m0.03s (16.09Mb)
  11. Behat Contexts <?php
 
 use Behat\Behat\Tester\Exception\PendingException;
 use Behat\Behat\Context\Context;
 use Behat\Behat\Context\SnippetAcceptingContext;


    use MageTest\MagentoExtension\Context\MagentoContext; class VisitorBrowsingContext extends MagentoContext implements Context, SnippetAcceptingContext
 {
 /*
 * @Given I have twitter enabled with a username
 */
 public function iHaveTwitterEnabledWithAUsername()
 {
 $configValue = Mage::getStoreConfig('jcowie/twitter/ active_username');
 if (isset($configValue)) {
 return true;
 } else {
 throw new RuntimeException('System configuration value not found');
 }
 }
 

  12. ➜ Magento behat Feature: A visitor can share via twitter

    In order to allow visitors to share our products As a site owner I need to offer a way to share via twitter my products Scenario: Visitor can share a product via twitter6 Given I have twitter enabled with a username System configuration value not found (RuntimeException) When I view a product page Then I should see a twitter block with my message configured --- Failed scenarios: features/visitor/twitter-integration.feature:6 1 scenario (1 failed) 3 steps (1 failed, 2 skipped) 0m0.02s (16.08Mb)
  13. Describe a new block ./bin/phpspec describe:block jcowie_twitter/twitter Specification for Jcowie_Twitter_Block_Twitter

    created in /vagrant/spec/ public/app/code/local/Jcowie/Twitter/Block/TwitterSpec.php. ./bin/phpspec r Jcowie_Twitter_Block_Twitter 10 ! it is initializable class Jcowie_Twitter_Block_Twitter does not exist. 94% 16 4 specs 16 examples (15 passed, 1 broken) 308ms Do you want me to create `Jcowie_Twitter_Block_Twitter` for you? [Y/n] Y Magento block Jcowie_Twitter_Block_Twitter created in '/vagrant/public/ app/code/local/Jcowie/Twitter/Block/Twitter.php'.
  14. Describe the class behaviour <?php
 
 namespace spec;
 
 use

    PhpSpec\ObjectBehavior;
 use Prophecy\Argument;
 
 class Jcowie_Twitter_Block_TwitterSpec extends ObjectBehavior
 {
 function it_should_return_the_twitter_username_and_url()
 {
 $this->getTwitterShareUrl() ->shouldReturn('http://twitter.com/jcowie');
 }
 }

  15. ./bin/phpspec r Jcowie_Twitter_Block_Twitter 15 ! it should return the configured

    twitter username and tweet url method Jcowie_Twitter_Block_Twitter::getTwitterShareUrl not found. 50% 50% 2 1 specs 2 examples (1 passed, 1 broken) 36ms Do you want me to create `Jcowie_Twitter_Block_Twitter::getTwitterShareUrl()` for you? [Y/n] Y Method Jcowie_Twitter_Block_Twitter::getTwitterShareUrl() has been created. ./bin/phpspec r Jcowie_Twitter_Block_Twitter 15 ✘ it should return the configured twitter username and tweet url expected "http://twitter.com/jcowie"..., but got null. 50% 50% 2
  16. What just happened ? • $this in spec refers to

    the class being tested • PHPSpec created the method for us <?php
 
 class Jcowie_Twitter_Block_Twitter
 {
 public function getTwitterShareUrl()
 {
 // TODO: write logic here
 }
 }

  17. Return back to green 100% 2 1 specs 2 examples

    (2 passed) 30ms <?php
 
 class Jcowie_Twitter_Block_Twitter
 {
 public function getTwitterShareUrl()
 {
 return 'http://twitter.com/jcowie';
 }
 }

  18. Refactor • Mage:: • Specs should not talk to other

    classes • Don’t spec code you do not own • Database calls
  19. Using adapters <?php 
 
 class Jcowie_Twitter_Model_Adapter_ConfigAdapter
 {
 public function

    getCoreConfigValue($path)
 {
 return Mage::getStoreConfig($path);
 }
 } 
 Don’t test what we Don’t Own!
  20. Inject into the block private $_configAdapter;
 
 public function __construct(array

    $services = array())
 {
 if (isset($services['config_adapter'])) {
 $this->_configAdapter = $services['config_adapter'];
 }
 if ( !$this->_configAdapter instanceof Jcowie_Twitter_Model_.._ConfigAdapter){
 $this->_configAdapter = new Jcowie_Twitter_Model_Adapter_ConfigAdapter();
 }
 } Dependency Injection
  21. Update the spec function let(\Jcowie_Twitter_Model_Adapter_ConfigAdapter $adapter)
 {
 $this->beConstructedWith(array('config_adapter' => $adapter));


    }
 
 function it_should_return_the_twitter_username_and_url($adapter)
 {
 $adapter->getCoreConfigValue(‘jcowie/twitter/twitter_username') ->willReturn(‘jcowie'); 
 $this->getTwitterShareUrl()->shouldReturn('http://twitter.com/ jcowie');
 }
 Mock the communication.
  22. Back to green ./bin/phpspec r --format=pretty Jcowie_Twitter_Block_Twitter 15 ✔ should

    return the configured twitter username and tweet url (55ms) 1 specs 1 examples (1 passed)
  23. Back to Behat Feature: Any customer to the site will

    see a twitter widget on the product page In order to allow visitors to share our products As a site owner I need to offer a way to share via twitter my products Scenario: Visitor can share a product via twitter Given I have twitter enabled with a username When I view a product page Then I should see a twitter block with my message configured 1 scenario (1 passed) 3 steps (3 passed) 0m1.47s (23.14Mb) Time to stop writing code!
  24. Lessons Learned • BDD is NOT Behat • Automation is

    a side effect • Conversation is king • Dont test Magento code.