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

It should! - BDD in practice

It should! - BDD in practice

How BDD helps you solve the murder on the Orient Express

Karol Sójko

June 17, 2013
Tweet

More Decks by Karol Sójko

Other Decks in Programming

Transcript

  1. IT SHOULD!
    BDD IN PRACTICE

    View Slide

  2. BEHAVIOR DRIVEN DEVELOPMENT
    =
    TEST DRIVEN DEVELOPMENT
    except it's done right

    View Slide

  3. TDD
    IS
    CODE-CENTRIC
    WHILE
    BDD
    IS
    COMMUNICATION-CENTRIC

    View Slide

  4. IT'S LIKE COKE
    PEPSI
    =
    COCA-COLA
    except it's done right

    View Slide

  5. BUT THIS IS NOT ABOUT WHAT BDD MEANS
    THIS IS ALL ABOUT
    TOOLS
    AND ...

    View Slide

  6. THE MURDER ON THE ORIENT EXPRESS

    View Slide

  7. MA'AM! CAN YOU TEST WHO YOU SAW?
    "What do you mean test? I can describe it if you like" - Ma'am
    ./bin/phpspec desc Suspect

    View Slide

  8. THE SUSPECTS
    "He was one of those types, you know"
    - Ma'am
    namespace spec\OrientExpress\Suspect;
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    class SuspectSpec extends ObjectBehavior
    {
    function it_is_initializable()
    {
    $this->shouldHaveType('OrientExpress\Suspect\Suspect');
    }
    }

    View Slide

  9. THE SUSPECTS
    "Don't yell at me! Be a dear and help me out." - Ma'am

    View Slide

  10. THE SUSPECTS
    namespace spec\OrientExpress\Suspect;
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    class SuspectSpec extends ObjectBehavior
    {
    //...
    function it_should_answer_questions()
    {
    $this->answer('Are you the killer?')
    ->shouldReturn('Nope, not me');
    }
    }

    View Slide

  11. THE SUSPECTS

    View Slide

  12. THE SUSPECTS
    namespace OrientExpress\Suspect;
    class Suspect
    {
    public function answer($question)
    {
    return 'Nope, not me';
    }
    }

    View Slide

  13. THE SUSPECTS - REFACTORING MADE EASY
    "Oh, I just remembered!"
    - Ma'am
    namespace spec\OrientExpress\Suspect;
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    class SuspectSpec extends ObjectBehavior
    {
    // ...
    function it_should_not_confess_to_wrong_questions_if_guilty()
    {
    $this->setGuilty(true);
    $this->answer('Are you the killer?')
    ->shouldReturn('Nope, not me');
    }
    }

    View Slide

  14. THE SUSPECTS - REFACTORING MADE EASY
    "Oh, I just remembered!"
    - Ma'am
    namespace spec\OrientExpress\Suspect;
    use PhpSpec\ObjectBehavior;
    use Prophecy\Argument;
    class SuspectSpec extends ObjectBehavior
    {
    // ...
    function it_should_confess_to_key_question_if_guilty()
    {
    $this->setGuilty(true);
    $this->answer('It was you!')
    ->shouldReturn('Mmmkay I confess');
    }
    }

    View Slide

  15. THE SUSPECTS
    namespace OrientExpress\Suspect;
    class Suspect
    {
    protected $keyQuestion = 'It was you!';
    protected $guilty = false;
    public function answer($question)
    {
    if ($this->guilty && $question == $this->keyQuestion) {
    return 'Mmmkay I confess';
    }
    return 'Nope, not me';
    }
    // ...
    }

    View Slide

  16. SIR! CAN YOU DESCRIBE WHO SOLVED IT?
    ./bin/phpspec desc Detective

    View Slide

  17. THE OLDSCHOOL DETECTIVE
    // Oppa PHPUnit style
    function testSolve()
    {
    // ...
    $crime = $this->getMock('OrientExpress\Crime\Crime',
    array('getSuspects'));
    $crime->expects($this->any())
    ->method('getSuspects')
    ->will($this->returnValue(array($suspect1, $suspect2));
    // NoOoOoooOoOoOoo!!!
    }

    View Slide

  18. THE DETECTIVE
    class DetectiveSpec extends ObjectBehavior
    {
    // ...
    /**
    * @param OrientExpress\Crime\Crime $crime
    * @param OrientExpress\Suspect\Suspect $suspect1
    * @param OrientExpress\Suspect\Suspect $suspect2
    */
    function it_should_be_able_to_solve_crimes($crime, $suspect1,
    $suspect2)
    {
    $crime->getSuspects()
    ->willReturn(array($suspect1, $suspect2));
    $suspect1->answer('It was you!')
    ->willReturn('Nope, not me');
    $suspect2->answer('It was you!')
    ->willReturn('Mmmkay I confess');
    $this->solve($crime)->shouldReturn($suspect2);
    }
    }

    View Slide

  19. THE DETECTIVE
    namespace OrientExpress\Investigators;
    use OrientExpress\Crime\Crime;
    class Detective
    {
    public function solve(Crime $crime)
    {
    foreach ($crime->getSuspects() as $suspect) {
    $answer = $suspect->answer('It was you!');
    if (preg_match('/confess/', $answer)) {
    return $suspect;
    }
    }
    }
    }

    View Slide

  20. WORKS AS DESCRIBED

    View Slide

  21. WHAT ABOUT THE SCOTLAND YARD?

    View Slide

  22. DOES THE POLICE FUNCTION PROPERLY?
    Feature:
    In order to know the crimes on orient express
    As a Scotland Yard API client
    I want to get access to the archives

    View Slide

  23. DOES THE POLICE FUNCTION PROPERLY?
    Background:
    Given the following crimes exist:
    | name |
    | "Murder on the Orient Express" |
    And the following detectives exist:
    | name |
    | "Herculse Poirot" |
    And the following suspects exist:
    | name |
    | "Princess Dragomiroff" |
    | "Count Adrenyi" |

    View Slide

  24. DOES THE POLICE FUNCTION PROPERLY?

    View Slide

  25. Scenario: Getting data from the Scotland Yard's archives
    Given crime "Murder on the Orient Express" was solved by "Hercules P
    oirot"
    And crime "Murder on the Orient Express" had suspects:
    | name |
    | "Princess Dragomiroff" |
    | "Count Adrenyi" |
    When I send GET request to "/api/crimes/ORIENT_EXPRESS_CRIME_ID"
    Then the response should contain json:
    """
    {
    "crime": {
    "name": "Murder on the Orient Express",
    "detective": {
    "name": "Hercules Poirot"
    },
    "suspects": [
    {
    "name": "Princes Dragomiroff"
    },
    {
    "name": "Count Adrenyi"
    }
    ]
    }
    }
    """

    View Slide

  26. WHY IS THIS SO IMPORTANT?
    BECAUSE EVERY CODE TELLS A STORY
    OR AT LEAST
    IT SHOULD!

    View Slide

  27. ?
    PhpSpec:
    Behat:
    Specs:
    ABOUT ME
    Karol Sójko
    Lead Software Architect @
    Twitter:
    Github:
    https://github.com/phpspec/phpspec
    https://github.com/Behat/Behat
    https://github.com/karolsojko/bdd-in-practice
    Comet Cult
    @karolsojko
    karolsojko

    View Slide