SlideShare a Scribd company logo
1 of 115
Download to read offline
BDD for        with
                                                PHPSpec



                            29th October 2011
                            Marcello Duarte

Saturday, 29 October 2011
whoami


                                   Marcello Duarte

                            Head of Training @ Ibuildings UK
                            Lead developer @ PHPSpec
                            Twitter @_md

Saturday, 29 October 2011
In the beginning
                               there was...

                                            TDD
  credits: http://www.flickr.com/photos/improveit/1574023621
Saturday, 29 October 2011
They saw that it was good



Saturday, 29 October 2011
$thou->shalt->test



   credits: http://www.flickr.com/photos/36829113@N05/3392940179/
Saturday, 29 October 2011
BDD


      credits: http://www.flickr.com/photos/psd/424257767/


Saturday, 29 October 2011
BDD
                            A way of teaching TDD



      credits: http://www.flickr.com/photos/psd/424257767/


Saturday, 29 October 2011
What to test?




               H
                 Where to begin?




                ow m uch


Saturday, 29 October 2011
                         to test i
                                  ?
                     What to call my test?
              How do I name my test?
                                   n one go?
BDD


      credits: http://www.flickr.com/photos/psd/424257767/


Saturday, 29 October 2011
BDD
                            Offers a common language


      credits: http://www.flickr.com/photos/psd/424257767/


Saturday, 29 October 2011
business

             user                      developer




Saturday, 29 October 2011
business

             user                       developer




                            behavior

Saturday, 29 October 2011
Saturday, 29 October 2011
                            © Manuscripts and Archives, Yale University Library.
                                                                                   Sapir-Whorf hypothesis
Language to express truth
                            vs...

Saturday, 29 October 2011
Language to discover truth



Saturday, 29 October 2011
Language influence thought



Saturday, 29 October 2011
BDD


      credits: http://www.flickr.com/photos/psd/424257767/


Saturday, 29 October 2011
BDD
                              A way to discover
                            what is useful to deliver


      credits: http://www.flickr.com/photos/psd/424257767/


Saturday, 29 October 2011
Saturday, 29 October 2011
BDD Outside in
                               Gherkin
                                Behat

                               PHPSpec




Saturday, 29 October 2011
Gherkin



Saturday, 29 October 2011
Feature: Organizers can open a call for paper
     As an event organizer
     I want a way to publish a centralized cfp form
     So that it’s easier for speakers to submit

   Scenario: Creation form with valid attributes
     Given I am in on "call-for-papers/add"
       When I fill in the following:
         | event             | PHPLondon Conference|
         | start_date        | 2012-02-06          |
         | limit_abstract_wc | 500                 |
         | why_you_field     | 1                   |
         | offer_hotel       | 1                   |
         | offer_travel      | 0                   |
       And I press "Create"
       Then I should see "The cfp was created successfully"




Saturday, 29 October 2011
behat.org


Saturday, 29 October 2011
Saturday, 29 October 2011
words matter



Saturday, 29 October 2011
$this->assertTrue(...




Saturday, 29 October 2011
$this->assertTrue(...



                            What am I going to test?




Saturday, 29 October 2011
$report = new Report;
            $this->assertTrue($report instanceof Report);




Saturday, 29 October 2011
/                           /
            $report = new Report;
            $this->assertTrue($report instanceof Report);




Saturday, 29 October 2011
$employee->should->...




Saturday, 29 October 2011
$employee->should->...



                            What is the expected behavior?




Saturday, 29 October 2011
Use Gherkin and Behat
        for specifying scenarios
                                  ∫
                             Use PHPSpec for
                            specifying classes
Saturday, 29 October 2011
expressiveness


Saturday, 29 October 2011
$this->assertTrue($employee->reportsTo($manager));




  $employee->should->reportTo($manager);




Saturday, 29 October 2011
phpspec.net




Saturday, 29 October 2011
Installing

                  $ sudo pear channel-discover pear.phpspec.net
                  $ sudo pear install --alldeps phpspec/PHPSpec




Saturday, 29 October 2011
“Specification, not
          verification” (Uncle Bob)
                        $this->assertEquals(0, $result);

                                  becomes
                            $result->should->be(0);



Saturday, 29 October 2011
class CalculatorTest


                                  becomes
                            class DescribeCalculator




Saturday, 29 October 2011
function testAddWithNoArguments()


                                     becomes
          function itReturnsZeroWithNoArguments()




Saturday, 29 October 2011
All together
     class DescribeStringCalculator extends PHPSpecContext
     {

           function itReturnsZeroWithNoArguments()
           {
             $calculator = $this->spec(new StringCalculator);
             $result = $calculator->add();

                 $result->should->be(0);
           }

     }




Saturday, 29 October 2011
Hooks

                             before()
                              after()
                            beforeAll()
                            afterAll()




Saturday, 29 October 2011
Setting initial state with before hook
     class DescribeStringCalculator extends PHPSpecContext
     {
       function before()
       {
         $this->calculator = $this->spec(new StringCalculator);
       }

          function itReturnsZeroWithNoArguments()
          {
            $result = $this->calculator->add();
            $result->should->be(0);
          }
     }




Saturday, 29 October 2011
class DescribeStringCalculator extends PHPSpecContext
     {
       private $calculator;

          function before()
          {
            $this->calculator = $this->spec(new StringCalculator);
          }

          function itReturnsZeroWithNoArguments()
          {
            $this->calculator->add()->should->equal(0);
          }

          function itReturnsTheBareNumber()
          {
            $this->calculator->add('42')->should->equal(42);
          }
     }
Saturday, 29 October 2011
Formatters
                              progress
                            documentation
                                 html


                             coming soon:
                                junit


Saturday, 29 October 2011
Progress Formatter
  $ phpspec StringCalculatorSpec.php -c
  .*.F

  Pending:
    String Calculator returns the bare number
       # Waiting to clarify the spec
       # ./spec/StringCalculatorSpec.php:19

  Failures:
    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 space separated string
         Failure/Error:
         Just because

  Finished in 0.056134 seconds
  4 examples, 1 failure, 1 pending

Saturday, 29 October 2011
HTML Formatter




Saturday, 29 October 2011
Documentation Formatter




Saturday, 29 October 2011
Matchers



Saturday, 29 October 2011
be($match)
                          equal($match)
                        beEqualTo($match)
                      beAnInstanceOf($match)
                             beEmpty()
                             beFalse()
                      beGreaterThan($match)
                  beGreaterThanOrEqualTo($match)



Saturday, 29 October 2011
And more matchers...



Saturday, 29 October 2011
beInteger()
                                beLessThan($match)
                            beLessThanOrEqualTo($match)
                                     beNull()
                                    beString()
                                     beTrue()
                              throwException($match)




Saturday, 29 October 2011
Predicate Matchers



Saturday, 29 October 2011
$cell = $this->spec(new Cell);
                            $cell->should->beAlive();



   class Cell
   {
       protected $alive = true;

                public function isAlive() {
                    return $this->alive;
                }
                ...
   }

Saturday, 29 October 2011
$newNode = $this->spec(new Node);
                    $newNode->shouldNot->haveChildren();



    class Node
    {
        protected $children = array();

                public function hasChildren() {
                    return count($this->children) > 0;
                }
                ...
    }

Saturday, 29 October 2011
Custom Matchers



Saturday, 29 October 2011
PHPSpecMatcherdefine('reportTo', function($supervisor) {
            return array (
                'match' => function($supportEngineer) use ($supervisor) {
                    return $supportEngineer->reportsTo($supervisor);
                },
                'failure_message_for_should' =>
                    function($supportEngineer) use ($supervisor) {
                        return "expected " . $supervisor->getName() .
                               " to report to " . $supervisor->getName();
                    }
            );
        });

        class DescribeSupportEngineer extends PHPSpecContext
        {   ...
            function itAddsNewCourses() {
                $john = new Supervisor("John Smith");
                $john->addToTeam($this->supportEngineer);
                $this->supportEngineer->should->reportTo($john);
            }
        }


Saturday, 29 October 2011
PHPSpec &


Saturday, 29 October 2011
Tool
                            framework.zend.com




Saturday, 29 October 2011
Installing
  $     sudo pear channel-discover pear.zfcampus.org
  $     sudo pear install zfcampus/zf
  $     zf create config
  $     vi ~/.zf.ini




Saturday, 29 October 2011
.zf.ini

  php.include_path = ".:/usr/share/pear"

  basicloader.classes.1     =   "Akrabat_Tool_DatabaseSchemaProvider"
  basicloader.classes.2     =   "PHPSpec_Context_Zend_Tool_Provider_Phpspec"
  basicloader.classes.3     =   "PHPSpec_Context_Zend_Tool_Provider_ModelSpec"
  basicloader.classes.4     =   "PHPSpec_Context_Zend_Tool_Provider_ViewSpec"
  basicloader.classes.5     =   "PHPSpec_Context_Zend_Tool_Provider_ControllerSpec"
  basicloader.classes.6     =   "PHPSpec_Context_Zend_Tool_Provider_ActionSpec"
  basicloader.classes.7     =   "PHPSpec_Context_Zend_Tool_Provider_Behat"




Saturday, 29 October 2011
create a project
  $ zf create project callconf
  Creating project at /var/www/callconf
  Note: This command created a web project, for more
  information setting up your VHOST, please see docs/README




Saturday, 29 October 2011
initialize PHPSpec
  $ cd callconf
  $ zf generate             phpspec
        create              spec
        create              spec/SpecHelper.php
        create              spec/.phpspec
        create              spec/models
        create              spec/views
        create              spec/controllers




Saturday, 29 October 2011
initialize Behat
  $ zf generate behat
  +d features - place your *.feature files here
  +d features/bootstrap - place bootstrap scripts and static
  files here
  +f features/bootstrap/FeatureContext.php - place your feature
  related code here




Saturday, 29 October 2011
Saturday, 29 October 2011
Views



Saturday, 29 October 2011
why specify the view?




Saturday, 29 October 2011
Controller and model to the point

                            Ensure we are focused on what matters

                                      Sustainable pace




Saturday, 29 October 2011
create a view spec




Saturday, 29 October 2011
create a view spec
  $ zf create view-spec add CallForPapers




Saturday, 29 October 2011
create a view spec
  $ zf create view-spec add CallForPapers
  Creating a view script in location /var/www/callconf/
  application/views/scripts/call-for-papers/add.phtml
  Creating a spec at /var/www/callconf/spec/views/call-for-
  papers/AddSpec.php




Saturday, 29 October 2011
Saturday, 29 October 2011
Spec created by default
         <?php

         namespace CallForPapers;

         require_once __DIR__ . '/../../SpecHelper.php';

         use PHPSpecContextZendView as ViewContext;

         class DescribeAdd extends ViewContext
         {
             function itRendersTheDefaultContent()
             {
                 $this->render();
                 $this->rendered->should->contain('CallForPapers');
                 $this->rendered->should->contain('add');
             }
         }




Saturday, 29 October 2011
what behaviors can we
                     describe in the view spec?



Saturday, 29 October 2011
Variables we need assigned

                            What content was rendered
                             (We can use selectors)




Saturday, 29 October 2011
Assigning Variables


    function itRendersTheTalkAbstract()
    {
        $marcello = $this->mock('Speaker', array('isVegetarian' => true));
        $this->assign('speaker', $marcello);
        $this->render();
        $this->rendered->should->contain('diet restrictions: vegetarian');
    }




Saturday, 29 October 2011
Controllers



Saturday, 29 October 2011
create a controller spec




Saturday, 29 October 2011
create a controller spec
  $ zf create controller-spec CallForPapers add,create




Saturday, 29 October 2011
create a controller spec
  $ zf create controller-spec CallForPapers add,create
  Creating a controller at /private/var/www/callconf/
  application/controllers/CallForPapersController.php
  Creating an add action method in controller CallForPapers
  Creating an create action method in controller CallForPapers
  Creating a spec at /private/var/www/callconf/spec/
  controllers/CallForPapersSpec.php




Saturday, 29 October 2011
Saturday, 29 October 2011
Spec created by default
    <?php

    require_once __DIR__ . '/../SpecHelper.php';

    class DescribeCallForPapers extends PHPSpecContextZendController
    {
        function itShouldBeSuccessfulToGetAdd()
        {
            $this->get('call-for-papers/add');
            $this->response->should->beSuccess();
        }


    }




Saturday, 29 October 2011
what behaviors do we want to
        describe in the controller spec?



Saturday, 29 October 2011
How do we want to route to its actions

                            What view variables we need assigned

                                What view we want rendered




Saturday, 29 October 2011
Routing and assigning
               function itShouldRouteToTheAddAction()
               {
                   $this->routeFor(array(
                       'controller' => 'call-for-papers',
                       'action' => 'add'
                   ))->should->be('/call-for-papers/add');
               }

                function itAssignsAddSubmissionFormVariable()
                {
                    $this->get('/call-for-papers/add');
                    $this->assigns('addSubmissionForm')->should->beAnInstanceOf(
                        'Application_Form_AddSubmissionForm'
                    );
                }




Saturday, 29 October 2011
Models



Saturday, 29 October 2011
create a model spec




Saturday, 29 October 2011
create a model spec
  $ zf create model-spec Speaker name:string,email:string




Saturday, 29 October 2011
create a model spec
  $ zf create model-spec Speaker name:string,email:string
  Creating a model at /private/var/www/callconf/application/
  models/Speaker.php
  Creating a db table at /private/var/www/callconf/
  application/models/DbTable/Speakers.php
  Creating a mapper at /private/var/www/callconf/application/
  models/SpeakerMapper.php
  Creating a spec at /private/var/www/callconf/spec/models/
  SpeakerSpec.php
  Creating migration scripts at /private/var/www/callconf/db/
  migrate/001-CreateSpeakersTable.php
  Updating project profile '/private/var/www/
  callconf/.zfproject.xml'



Saturday, 29 October 2011
Saturday, 29 October 2011
Spec created by default
<?php

require_once __DIR__ . '/../SpecHelper.php';

use Application_Model_Speaker as Speaker;

class DescribeSpeaker extends PHPSpecContext
{
  function before()
  {
    $this->validAttributes = array(
       'name' => 'value for name',
       'email' => 'value for email',
    );
  }

    function itShouldCreateANewInstanceGivenValidAttributes()
    {
      $this->speaker = $this->spec(Speaker::create($this->validAttributes));
      $this->speaker->should->beValid();
    }
}
Saturday, 29 October 2011
what behaviors can we
                 describe in the model spec?



Saturday, 29 October 2011
Business logic

                                     Validation

                     Spying results from data source operations




Saturday, 29 October 2011
Business Logic

class DescribeSpeaker extends PHPSpecContext
{
  function before()
  {
    $this->validAttributes = array(
       'name' => 'Marcello Duarte',
       'email' => 'marcello@ibuildings.com',
       'diet_restriction' => 'vegetarian',
    );
    $this->speaker = $this->spec(Speaker::create($this->validAttributes));
  }

    function itGetsExtraRatingPointsForTalkIfVegetarian()
    {
      $this->speaker->should->haveExtraPoints();
    }
}



Saturday, 29 October 2011
Business Logic



class Speaker
{
  //... other methods

    function hasExtraPoints()
    {
      return stripos($this->getDietRestrictions(), 'vegetarian') !== false;
    }
}




Saturday, 29 October 2011
Real database hits?




Saturday, 29 October 2011
Avoid

                               Sometimes, for confidence

                            When testing data access objects




Saturday, 29 October 2011
Dependency chains




Saturday, 29 October 2011
Dependencies can be hard to manage

class DescribeEvent extends PHPSpecContext
{
    function itDoesSomethingWhenYouHaveSpeakerAllocated()
    {
        $event = new Event(
            new Organizer('John Smith',
                new Organization('Ibuildings')
            )
        );
        $event->addSpeaker(new Speaker('Rowan'), new Slot(’10:30’),
                            new Room('A'));
        $event->addSpeaker(new Speaker('Ben'), new Slot(’10:30’),
                            new Room('B'));
        // specify expected behavior
    }
}




Saturday, 29 October 2011
Usually dependencies are replaced with
                                  doubles when writing specs

                             We can use a framework like Mockery

                             But if you really need the real thing




Saturday, 29 October 2011
Object Mother



Saturday, 29 October 2011
Dependencies can be hard to manage



class DescribeEvent extends PHPSpecContext
{
    function itDoesSomethingWhenYouHaveSpeakerAllocated()
    {
        $exampleEvent = ExampleEvent::newWithSimultaneousSpeakers();

                  // specify expected event behavior
         }
}




Saturday, 29 October 2011
Code duplication

                            Too many methods




Saturday, 29 October 2011
Test Data Builder



Saturday, 29 October 2011
Is created with save “empty” objects

                                   Has a fluent interface

                                    Has a build method




Saturday, 29 October 2011
Dependencies can be hard to manage


class DescribeEvent extends PHPSpecContext
{
    function itDoesSomethingWhenYouHaveSpeakerAllocated()
    {
        $eventBuilder = new EventBuilder();
        $organizerBuilder = new OrganizerBuilder();

                  $event = $eventBuilder->withOrganizer(
                                $organizerBuilder->withOrganization()->build()
                           )->withConflictingSpeakers()
                            ->build();

                  // specify expected event behavior
         }
}




Saturday, 29 October 2011
phactory.org




Saturday, 29 October 2011
installing




Saturday, 29 October 2011
installing
  $ sudo pear channel-discover pearhub.org




Saturday, 29 October 2011
installing
  $ sudo pear channel-discover pearhub.org
  $ sudo pear install pearhub/Phactory




Saturday, 29 October 2011
Needs a Pdo connection

                            Get from default adapter




Saturday, 29 October 2011
Create a connection

         protected function _initPhactory()
         {
             Phactory::setConnection(
                 Zend_Db_Table_Abstract::getDefaultAdapter());
             return Phactory::getConnection();
         }




Saturday, 29 October 2011
Define table blueprints

     // spec/factories.php

     Phactory::define('speaker', array(
                 'name' => 'John Smith',
                 'email' => 'john@smith.com'));




Saturday, 29 October 2011
Create objects
     // in one of my specs

     $ben = Phactory::create('speaker', array('name' => 'Rowan'));
     $rowan = Phactory::create('speaker', array('name' => 'Ben'));



     // Phactory_Row objects
     echo $ben->name // prints Ben




Saturday, 29 October 2011
Questions?




                                         223
Saturday, 29 October 2011
Thank you!

                            http://joind.in/4318
                            http://slidesha.re/tcGM93
                            Marcello Duarte
                            @_md



                                    is hiring. Come talk to me.

                                                                  224
Saturday, 29 October 2011

More Related Content

Similar to BDD For Zend Framework With PHPSpec

Scaling websites with RabbitMQ A(rlvaro Videla)
Scaling websites with RabbitMQ   A(rlvaro Videla)Scaling websites with RabbitMQ   A(rlvaro Videla)
Scaling websites with RabbitMQ A(rlvaro Videla)Ontico
 
Building an alarm clock with node.js
Building an alarm clock with node.jsBuilding an alarm clock with node.js
Building an alarm clock with node.jsFelix Geisendörfer
 
NodeJS, CoffeeScript & Real-time Web
NodeJS, CoffeeScript & Real-time WebNodeJS, CoffeeScript & Real-time Web
NodeJS, CoffeeScript & Real-time WebJakub Nesetril
 
Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)ecommerce poland expo
 
Html5 episode 2
Html5 episode 2Html5 episode 2
Html5 episode 2Eric Smith
 
Ruby para-programadores-php
Ruby para-programadores-phpRuby para-programadores-php
Ruby para-programadores-phpJuan Maiz
 
international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPsmueller_sandsmedia
 
WordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMSWordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMSChris Olbekson
 
Unit Testing in SilverStripe
Unit Testing in SilverStripeUnit Testing in SilverStripe
Unit Testing in SilverStripeIngo Schommer
 
Intro to HTML5 Game Programming
Intro to HTML5 Game ProgrammingIntro to HTML5 Game Programming
Intro to HTML5 Game ProgrammingJames Williams
 
잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기형우 안
 
DBXTalk: Smalltalk Relational Database Suite
DBXTalk: Smalltalk Relational Database SuiteDBXTalk: Smalltalk Relational Database Suite
DBXTalk: Smalltalk Relational Database SuiteMariano Martínez Peck
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with TransmogrifierClayton Parker
 
Drupalmatinee.devtools.v2
Drupalmatinee.devtools.v2Drupalmatinee.devtools.v2
Drupalmatinee.devtools.v2Joeri Poesen
 
Concurrency
ConcurrencyConcurrency
Concurrencyehuard
 
iPhone App from concept to product
iPhone App from concept to productiPhone App from concept to product
iPhone App from concept to productjoeysim
 

Similar to BDD For Zend Framework With PHPSpec (20)

Scaling websites with RabbitMQ A(rlvaro Videla)
Scaling websites with RabbitMQ   A(rlvaro Videla)Scaling websites with RabbitMQ   A(rlvaro Videla)
Scaling websites with RabbitMQ A(rlvaro Videla)
 
Building an alarm clock with node.js
Building an alarm clock with node.jsBuilding an alarm clock with node.js
Building an alarm clock with node.js
 
NodeJS, CoffeeScript & Real-time Web
NodeJS, CoffeeScript & Real-time WebNodeJS, CoffeeScript & Real-time Web
NodeJS, CoffeeScript & Real-time Web
 
Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)Backbone.js - Michał Taberski (PRUG 2.0)
Backbone.js - Michał Taberski (PRUG 2.0)
 
Html5 episode 2
Html5 episode 2Html5 episode 2
Html5 episode 2
 
Ruby para-programadores-php
Ruby para-programadores-phpRuby para-programadores-php
Ruby para-programadores-php
 
Mobile WPO
Mobile WPOMobile WPO
Mobile WPO
 
international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHP
 
WordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMSWordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMS
 
ActiveRecord 2.3
ActiveRecord 2.3ActiveRecord 2.3
ActiveRecord 2.3
 
Node Stream
Node StreamNode Stream
Node Stream
 
Unit Testing in SilverStripe
Unit Testing in SilverStripeUnit Testing in SilverStripe
Unit Testing in SilverStripe
 
Intro to HTML5 Game Programming
Intro to HTML5 Game ProgrammingIntro to HTML5 Game Programming
Intro to HTML5 Game Programming
 
잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기
 
DBXTalk: Smalltalk Relational Database Suite
DBXTalk: Smalltalk Relational Database SuiteDBXTalk: Smalltalk Relational Database Suite
DBXTalk: Smalltalk Relational Database Suite
 
Laying Pipe with Transmogrifier
Laying Pipe with TransmogrifierLaying Pipe with Transmogrifier
Laying Pipe with Transmogrifier
 
RunDeck
RunDeckRunDeck
RunDeck
 
Drupalmatinee.devtools.v2
Drupalmatinee.devtools.v2Drupalmatinee.devtools.v2
Drupalmatinee.devtools.v2
 
Concurrency
ConcurrencyConcurrency
Concurrency
 
iPhone App from concept to product
iPhone App from concept to productiPhone App from concept to product
iPhone App from concept to product
 

More from Marcello Duarte

Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHPMarcello Duarte
 
Introducing Eager Design
Introducing Eager DesignIntroducing Eager Design
Introducing Eager DesignMarcello Duarte
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Understanding craftsmanship
Understanding craftsmanshipUnderstanding craftsmanship
Understanding craftsmanshipMarcello Duarte
 
The framework as an implementation detail
The framework as an implementation detailThe framework as an implementation detail
The framework as an implementation detailMarcello Duarte
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesMarcello Duarte
 
Emergent design with phpspec
Emergent design with phpspecEmergent design with phpspec
Emergent design with phpspecMarcello Duarte
 
Pair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical thingsPair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical thingsMarcello Duarte
 

More from Marcello Duarte (16)

Functional Structures in PHP
Functional Structures in PHPFunctional Structures in PHP
Functional Structures in PHP
 
Empathy from Agility
Empathy from AgilityEmpathy from Agility
Empathy from Agility
 
Introducing Eager Design
Introducing Eager DesignIntroducing Eager Design
Introducing Eager Design
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Barely Enough Design
Barely Enough DesignBarely Enough Design
Barely Enough Design
 
Transitioning to Agile
Transitioning to AgileTransitioning to Agile
Transitioning to Agile
 
Understanding craftsmanship
Understanding craftsmanshipUnderstanding craftsmanship
Understanding craftsmanship
 
Hexagonal symfony
Hexagonal symfonyHexagonal symfony
Hexagonal symfony
 
The framework as an implementation detail
The framework as an implementation detailThe framework as an implementation detail
The framework as an implementation detail
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
 
Emergent design with phpspec
Emergent design with phpspecEmergent design with phpspec
Emergent design with phpspec
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Pair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical thingsPair Programming, TDD and other impractical things
Pair Programming, TDD and other impractical things
 
Deliberate practice
Deliberate practiceDeliberate practice
Deliberate practice
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 

Recently uploaded

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 

Recently uploaded (20)

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 

BDD For Zend Framework With PHPSpec

  • 1. BDD for with PHPSpec 29th October 2011 Marcello Duarte Saturday, 29 October 2011
  • 2. whoami Marcello Duarte Head of Training @ Ibuildings UK Lead developer @ PHPSpec Twitter @_md Saturday, 29 October 2011
  • 3. In the beginning there was... TDD credits: http://www.flickr.com/photos/improveit/1574023621 Saturday, 29 October 2011
  • 4. They saw that it was good Saturday, 29 October 2011
  • 5. $thou->shalt->test credits: http://www.flickr.com/photos/36829113@N05/3392940179/ Saturday, 29 October 2011
  • 6. BDD credits: http://www.flickr.com/photos/psd/424257767/ Saturday, 29 October 2011
  • 7. BDD A way of teaching TDD credits: http://www.flickr.com/photos/psd/424257767/ Saturday, 29 October 2011
  • 8. What to test? H Where to begin? ow m uch Saturday, 29 October 2011 to test i ? What to call my test? How do I name my test? n one go?
  • 9. BDD credits: http://www.flickr.com/photos/psd/424257767/ Saturday, 29 October 2011
  • 10. BDD Offers a common language credits: http://www.flickr.com/photos/psd/424257767/ Saturday, 29 October 2011
  • 11. business user developer Saturday, 29 October 2011
  • 12. business user developer behavior Saturday, 29 October 2011
  • 13. Saturday, 29 October 2011 © Manuscripts and Archives, Yale University Library. Sapir-Whorf hypothesis
  • 14. Language to express truth vs... Saturday, 29 October 2011
  • 15. Language to discover truth Saturday, 29 October 2011
  • 17. BDD credits: http://www.flickr.com/photos/psd/424257767/ Saturday, 29 October 2011
  • 18. BDD A way to discover what is useful to deliver credits: http://www.flickr.com/photos/psd/424257767/ Saturday, 29 October 2011
  • 20. BDD Outside in Gherkin Behat PHPSpec Saturday, 29 October 2011
  • 22. Feature: Organizers can open a call for paper As an event organizer I want a way to publish a centralized cfp form So that it’s easier for speakers to submit Scenario: Creation form with valid attributes Given I am in on "call-for-papers/add" When I fill in the following: | event | PHPLondon Conference| | start_date | 2012-02-06 | | limit_abstract_wc | 500 | | why_you_field | 1 | | offer_hotel | 1 | | offer_travel | 0 | And I press "Create" Then I should see "The cfp was created successfully" Saturday, 29 October 2011
  • 27. $this->assertTrue(... What am I going to test? Saturday, 29 October 2011
  • 28. $report = new Report; $this->assertTrue($report instanceof Report); Saturday, 29 October 2011
  • 29. / / $report = new Report; $this->assertTrue($report instanceof Report); Saturday, 29 October 2011
  • 31. $employee->should->... What is the expected behavior? Saturday, 29 October 2011
  • 32. Use Gherkin and Behat for specifying scenarios ∫ Use PHPSpec for specifying classes Saturday, 29 October 2011
  • 36. Installing $ sudo pear channel-discover pear.phpspec.net $ sudo pear install --alldeps phpspec/PHPSpec Saturday, 29 October 2011
  • 37. “Specification, not verification” (Uncle Bob) $this->assertEquals(0, $result); becomes $result->should->be(0); Saturday, 29 October 2011
  • 38. class CalculatorTest becomes class DescribeCalculator Saturday, 29 October 2011
  • 39. function testAddWithNoArguments() becomes function itReturnsZeroWithNoArguments() Saturday, 29 October 2011
  • 40. All together class DescribeStringCalculator extends PHPSpecContext { function itReturnsZeroWithNoArguments() { $calculator = $this->spec(new StringCalculator); $result = $calculator->add(); $result->should->be(0); } } Saturday, 29 October 2011
  • 41. Hooks before() after() beforeAll() afterAll() Saturday, 29 October 2011
  • 42. Setting initial state with before hook class DescribeStringCalculator extends PHPSpecContext { function before() { $this->calculator = $this->spec(new StringCalculator); } function itReturnsZeroWithNoArguments() { $result = $this->calculator->add(); $result->should->be(0); } } Saturday, 29 October 2011
  • 43. class DescribeStringCalculator extends PHPSpecContext { private $calculator; function before() { $this->calculator = $this->spec(new StringCalculator); } function itReturnsZeroWithNoArguments() { $this->calculator->add()->should->equal(0); } function itReturnsTheBareNumber() { $this->calculator->add('42')->should->equal(42); } } Saturday, 29 October 2011
  • 44. Formatters progress documentation html coming soon: junit Saturday, 29 October 2011
  • 45. Progress Formatter $ phpspec StringCalculatorSpec.php -c .*.F Pending: String Calculator returns the bare number # Waiting to clarify the spec # ./spec/StringCalculatorSpec.php:19 Failures: 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 space separated string Failure/Error: Just because Finished in 0.056134 seconds 4 examples, 1 failure, 1 pending Saturday, 29 October 2011
  • 49. be($match) equal($match) beEqualTo($match) beAnInstanceOf($match) beEmpty() beFalse() beGreaterThan($match) beGreaterThanOrEqualTo($match) Saturday, 29 October 2011
  • 51. beInteger() beLessThan($match) beLessThanOrEqualTo($match) beNull() beString() beTrue() throwException($match) Saturday, 29 October 2011
  • 53. $cell = $this->spec(new Cell); $cell->should->beAlive(); class Cell { protected $alive = true; public function isAlive() { return $this->alive; } ... } Saturday, 29 October 2011
  • 54. $newNode = $this->spec(new Node); $newNode->shouldNot->haveChildren(); class Node { protected $children = array(); public function hasChildren() { return count($this->children) > 0; } ... } Saturday, 29 October 2011
  • 56. PHPSpecMatcherdefine('reportTo', function($supervisor) { return array ( 'match' => function($supportEngineer) use ($supervisor) { return $supportEngineer->reportsTo($supervisor); }, 'failure_message_for_should' => function($supportEngineer) use ($supervisor) { return "expected " . $supervisor->getName() . " to report to " . $supervisor->getName(); } ); }); class DescribeSupportEngineer extends PHPSpecContext { ... function itAddsNewCourses() { $john = new Supervisor("John Smith"); $john->addToTeam($this->supportEngineer); $this->supportEngineer->should->reportTo($john); } } Saturday, 29 October 2011
  • 57. PHPSpec & Saturday, 29 October 2011
  • 58. Tool framework.zend.com Saturday, 29 October 2011
  • 59. Installing $ sudo pear channel-discover pear.zfcampus.org $ sudo pear install zfcampus/zf $ zf create config $ vi ~/.zf.ini Saturday, 29 October 2011
  • 60. .zf.ini php.include_path = ".:/usr/share/pear" basicloader.classes.1 = "Akrabat_Tool_DatabaseSchemaProvider" basicloader.classes.2 = "PHPSpec_Context_Zend_Tool_Provider_Phpspec" basicloader.classes.3 = "PHPSpec_Context_Zend_Tool_Provider_ModelSpec" basicloader.classes.4 = "PHPSpec_Context_Zend_Tool_Provider_ViewSpec" basicloader.classes.5 = "PHPSpec_Context_Zend_Tool_Provider_ControllerSpec" basicloader.classes.6 = "PHPSpec_Context_Zend_Tool_Provider_ActionSpec" basicloader.classes.7 = "PHPSpec_Context_Zend_Tool_Provider_Behat" Saturday, 29 October 2011
  • 61. create a project $ zf create project callconf Creating project at /var/www/callconf Note: This command created a web project, for more information setting up your VHOST, please see docs/README Saturday, 29 October 2011
  • 62. initialize PHPSpec $ cd callconf $ zf generate phpspec create spec create spec/SpecHelper.php create spec/.phpspec create spec/models create spec/views create spec/controllers Saturday, 29 October 2011
  • 63. initialize Behat $ zf generate behat +d features - place your *.feature files here +d features/bootstrap - place bootstrap scripts and static files here +f features/bootstrap/FeatureContext.php - place your feature related code here Saturday, 29 October 2011
  • 66. why specify the view? Saturday, 29 October 2011
  • 67. Controller and model to the point Ensure we are focused on what matters Sustainable pace Saturday, 29 October 2011
  • 68. create a view spec Saturday, 29 October 2011
  • 69. create a view spec $ zf create view-spec add CallForPapers Saturday, 29 October 2011
  • 70. create a view spec $ zf create view-spec add CallForPapers Creating a view script in location /var/www/callconf/ application/views/scripts/call-for-papers/add.phtml Creating a spec at /var/www/callconf/spec/views/call-for- papers/AddSpec.php Saturday, 29 October 2011
  • 72. Spec created by default <?php namespace CallForPapers; require_once __DIR__ . '/../../SpecHelper.php'; use PHPSpecContextZendView as ViewContext; class DescribeAdd extends ViewContext { function itRendersTheDefaultContent() { $this->render(); $this->rendered->should->contain('CallForPapers'); $this->rendered->should->contain('add'); } } Saturday, 29 October 2011
  • 73. what behaviors can we describe in the view spec? Saturday, 29 October 2011
  • 74. Variables we need assigned What content was rendered (We can use selectors) Saturday, 29 October 2011
  • 75. Assigning Variables function itRendersTheTalkAbstract() { $marcello = $this->mock('Speaker', array('isVegetarian' => true)); $this->assign('speaker', $marcello); $this->render(); $this->rendered->should->contain('diet restrictions: vegetarian'); } Saturday, 29 October 2011
  • 77. create a controller spec Saturday, 29 October 2011
  • 78. create a controller spec $ zf create controller-spec CallForPapers add,create Saturday, 29 October 2011
  • 79. create a controller spec $ zf create controller-spec CallForPapers add,create Creating a controller at /private/var/www/callconf/ application/controllers/CallForPapersController.php Creating an add action method in controller CallForPapers Creating an create action method in controller CallForPapers Creating a spec at /private/var/www/callconf/spec/ controllers/CallForPapersSpec.php Saturday, 29 October 2011
  • 81. Spec created by default <?php require_once __DIR__ . '/../SpecHelper.php'; class DescribeCallForPapers extends PHPSpecContextZendController { function itShouldBeSuccessfulToGetAdd() { $this->get('call-for-papers/add'); $this->response->should->beSuccess(); } } Saturday, 29 October 2011
  • 82. what behaviors do we want to describe in the controller spec? Saturday, 29 October 2011
  • 83. How do we want to route to its actions What view variables we need assigned What view we want rendered Saturday, 29 October 2011
  • 84. Routing and assigning function itShouldRouteToTheAddAction() { $this->routeFor(array( 'controller' => 'call-for-papers', 'action' => 'add' ))->should->be('/call-for-papers/add'); } function itAssignsAddSubmissionFormVariable() { $this->get('/call-for-papers/add'); $this->assigns('addSubmissionForm')->should->beAnInstanceOf( 'Application_Form_AddSubmissionForm' ); } Saturday, 29 October 2011
  • 86. create a model spec Saturday, 29 October 2011
  • 87. create a model spec $ zf create model-spec Speaker name:string,email:string Saturday, 29 October 2011
  • 88. create a model spec $ zf create model-spec Speaker name:string,email:string Creating a model at /private/var/www/callconf/application/ models/Speaker.php Creating a db table at /private/var/www/callconf/ application/models/DbTable/Speakers.php Creating a mapper at /private/var/www/callconf/application/ models/SpeakerMapper.php Creating a spec at /private/var/www/callconf/spec/models/ SpeakerSpec.php Creating migration scripts at /private/var/www/callconf/db/ migrate/001-CreateSpeakersTable.php Updating project profile '/private/var/www/ callconf/.zfproject.xml' Saturday, 29 October 2011
  • 90. Spec created by default <?php require_once __DIR__ . '/../SpecHelper.php'; use Application_Model_Speaker as Speaker; class DescribeSpeaker extends PHPSpecContext { function before() { $this->validAttributes = array( 'name' => 'value for name', 'email' => 'value for email', ); } function itShouldCreateANewInstanceGivenValidAttributes() { $this->speaker = $this->spec(Speaker::create($this->validAttributes)); $this->speaker->should->beValid(); } } Saturday, 29 October 2011
  • 91. what behaviors can we describe in the model spec? Saturday, 29 October 2011
  • 92. Business logic Validation Spying results from data source operations Saturday, 29 October 2011
  • 93. Business Logic class DescribeSpeaker extends PHPSpecContext { function before() { $this->validAttributes = array( 'name' => 'Marcello Duarte', 'email' => 'marcello@ibuildings.com', 'diet_restriction' => 'vegetarian', ); $this->speaker = $this->spec(Speaker::create($this->validAttributes)); } function itGetsExtraRatingPointsForTalkIfVegetarian() { $this->speaker->should->haveExtraPoints(); } } Saturday, 29 October 2011
  • 94. Business Logic class Speaker { //... other methods function hasExtraPoints() { return stripos($this->getDietRestrictions(), 'vegetarian') !== false; } } Saturday, 29 October 2011
  • 95. Real database hits? Saturday, 29 October 2011
  • 96. Avoid Sometimes, for confidence When testing data access objects Saturday, 29 October 2011
  • 98. Dependencies can be hard to manage class DescribeEvent extends PHPSpecContext { function itDoesSomethingWhenYouHaveSpeakerAllocated() { $event = new Event( new Organizer('John Smith', new Organization('Ibuildings') ) ); $event->addSpeaker(new Speaker('Rowan'), new Slot(’10:30’), new Room('A')); $event->addSpeaker(new Speaker('Ben'), new Slot(’10:30’), new Room('B')); // specify expected behavior } } Saturday, 29 October 2011
  • 99. Usually dependencies are replaced with doubles when writing specs We can use a framework like Mockery But if you really need the real thing Saturday, 29 October 2011
  • 100. Object Mother Saturday, 29 October 2011
  • 101. Dependencies can be hard to manage class DescribeEvent extends PHPSpecContext { function itDoesSomethingWhenYouHaveSpeakerAllocated() { $exampleEvent = ExampleEvent::newWithSimultaneousSpeakers(); // specify expected event behavior } } Saturday, 29 October 2011
  • 102. Code duplication Too many methods Saturday, 29 October 2011
  • 103. Test Data Builder Saturday, 29 October 2011
  • 104. Is created with save “empty” objects Has a fluent interface Has a build method Saturday, 29 October 2011
  • 105. Dependencies can be hard to manage class DescribeEvent extends PHPSpecContext { function itDoesSomethingWhenYouHaveSpeakerAllocated() { $eventBuilder = new EventBuilder(); $organizerBuilder = new OrganizerBuilder(); $event = $eventBuilder->withOrganizer( $organizerBuilder->withOrganization()->build() )->withConflictingSpeakers() ->build(); // specify expected event behavior } } Saturday, 29 October 2011
  • 108. installing $ sudo pear channel-discover pearhub.org Saturday, 29 October 2011
  • 109. installing $ sudo pear channel-discover pearhub.org $ sudo pear install pearhub/Phactory Saturday, 29 October 2011
  • 110. Needs a Pdo connection Get from default adapter Saturday, 29 October 2011
  • 111. Create a connection protected function _initPhactory() { Phactory::setConnection( Zend_Db_Table_Abstract::getDefaultAdapter()); return Phactory::getConnection(); } Saturday, 29 October 2011
  • 112. Define table blueprints // spec/factories.php Phactory::define('speaker', array( 'name' => 'John Smith', 'email' => 'john@smith.com')); Saturday, 29 October 2011
  • 113. Create objects // in one of my specs $ben = Phactory::create('speaker', array('name' => 'Rowan')); $rowan = Phactory::create('speaker', array('name' => 'Ben')); // Phactory_Row objects echo $ben->name // prints Ben Saturday, 29 October 2011
  • 114. Questions? 223 Saturday, 29 October 2011
  • 115. Thank you! http://joind.in/4318 http://slidesha.re/tcGM93 Marcello Duarte @_md is hiring. Come talk to me. 224 Saturday, 29 October 2011