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

Behat - BDD for PHP

Gasol Wu
November 03, 2012

Behat - BDD for PHP

Gasol Wu

November 03, 2012
Tweet

More Decks by Gasol Wu

Other Decks in Programming

Transcript

  1. Behat - BDD for PHP
    2012/11/03
    Gasol Wu @ PHPConf Taiwan
    12年11月3⽇日星期六

    View Slide

  2. About Me
    • @gasolwu
    • https://github.com/Gasol
    • writes PHP since 2009
    12年11月3⽇日星期六

    View Slide

  3. Agenda
    • Introduction to BDD
    • Gherkin Syntax
    • Behat by example
    • Demo
    12年11月3⽇日星期六

    View Slide

  4. BDD?
    12年11月3⽇日星期六

    View Slide

  5. Behavior
    Driven
    Development
    12年11月3⽇日星期六

    View Slide

  6. BDD
    • BDD ~= TDD + DDD
    • Specification as Ubiquitous Language
    • Colloboration between developers and
    non-techies
    • “outside-in” methodology driven by
    business value
    12年11月3⽇日星期六

    View Slide

  7. Writing tests is Hard
    • Where to start
    • What to test and what not to test
    • How much to test in one go
    • What to call their tests
    • How to understand why a test fails
    12年11月3⽇日星期六

    View Slide

  8. What makes BDD
    diffirent?
    12年11月3⽇日星期六

    View Slide

  9. • Starts at outside by identifying business
    outcomes
    • Then drills down into the feature set
    • Each feature is captured as a “story”
    12年11月3⽇日星期六

    View Slide

  10. In order to see the directory structure
    As a UNIX user
    I need to be able to list the current
    directory's contents
    Feature: List directory contents
    12年11月3⽇日星期六

    View Slide

  11. In order to [meet some goal]
    As a [role]
    I need/want [a feature]
    12年11月3⽇日星期六

    View Slide

  12. Scenario: List 2 files in a directory
    Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    12年11月3⽇日星期六

    View Slide

  13. Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    12年11月3⽇日星期六

    View Slide

  14. Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    Context
    12年11月3⽇日星期六

    View Slide

  15. Given
    (Context)
    Given there are no users on site
    Given the database is clean
    Given I am logged in as "Everzet"
    12年11月3⽇日星期六

    View Slide

  16. Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    Context
    12年11月3⽇日星期六

    View Slide

  17. Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    Context
    Event(s)
    12年11月3⽇日星期六

    View Slide

  18. When
    (Event)
    When I am on "/some/page"
    When I fill "username" with "everzet"
    When I fill "password" with "123456"
    When I press "login"
    When I call "ls -la"
    12年11月3⽇日星期六

    View Slide

  19. Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    Context
    Event(s)
    12年11月3⽇日星期六

    View Slide

  20. Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    Context
    Event(s)
    Outcome(s)
    12年11月3⽇日星期六

    View Slide

  21. Then
    (Outcome)
    Then the output should be "hello"
    Then I see something
    But I don't see something else
    12年11月3⽇日星期六

    View Slide

  22. Put them together
    12年11月3⽇日星期六

    View Slide

  23. Feature: ls
    In order to see the directory structure
    As a UNIX user
    I need to be able to list the current
    directory's contents
    Scenario: List 2 files in a directory
    Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    12年11月3⽇日星期六

    View Slide

  24. Feature: ls
    In order to see the directory structure
    As a UNIX user
    I need to be able to list the current
    directory's contents
    Scenario: List 2 files in a directory
    Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    12年11月3⽇日星期六

    View Slide

  25. 12年11月3⽇日星期六

    View Slide

  26. Gherkin
    • business-readable DSL for BDD
    • Spoken 37+ languages, including Chinese
    • .feature extension
    • line-oriented language
    12年11月3⽇日星期六

    View Slide

  27. https://github.com/cucumber/gherkin/blob/master/lib/gherkin/i18n.json
    # language: en
    Scenario: Regular numbers
    Given I have entered 3 into the calculator
    And I have entered 2 into the calculator
    When I press divide
    Then the result should be 1.5 on the screen
    # language: de
    Szenario: Normale Zahlen
    Gegeben sei ich habe 3 in den Taschenrechner eingegeben
    Und ich habe 2 in den Taschenrechner eingegeben
    Wenn ich divide drücke
    Dann sollte das Ergebniss auf dem Bildschirm 1.5 sein
    # language: zh-TW
    場景: 將兩個數相除
    假設我已經在計算機上輸⼊入 3
    ⽽而且我已經在計算機上輸⼊入 2
    當我按下 divide
    那麼螢幕上應該顯⽰示 1.5
    # language: ja
    シナリオ: ふつうの数値
    前提 3 を⼊入⼒力
    かつ 2 を⼊入⼒力
    もし divide を押した
    ならば 1.5 を表⽰示
    12年11月3⽇日星期六

    View Slide

  28. • Inspired by Ruby’s Cucumber
    • know Gherken
    • PHP 5.3+
    • Annotation
    12年11月3⽇日星期六

    View Slide

  29. “Overall I’ve been really impressed with Behat.
    I would never have imagined that Behat and
    Mink were going to even compare to
    Cucumber and Capybara, but it does!!”
    Brett, Lead Web Developer at BBC
    12年11月3⽇日星期六

    View Slide

  30. $ curl -O http://behat.org/downloads/behat.phar
    12年11月3⽇日星期六

    View Slide

  31. $ behat --init
    .
    └── features
    └── bootstrap
    └── FeatureContext.php
    12年11月3⽇日星期六

    View Slide

  32. 1 2
    3 class FeatureContext extends BehatContext
    4 {
    5 public function __construct(array $parameters)
    6 {
    7 // Initialize your context here
    8 }
    9
    10 //
    11 // Place your definition and hook methods here:
    12 //
    13 // /**
    14 // * @Given /^I have done something with "([^"]*)"$/
    15 // */
    16 // public function iHaveDoneSomethingWith($argument)
    17 // {
    18 // doSomethingWith($argument);
    19 // }
    20 //
    21 }
    12年11月3⽇日星期六

    View Slide

  33. ls.feature
    1 Feature: ls
    2 In order to see the directory structure
    3 As a UNIX user
    4 I need to be able to list the current directory's
    contents
    5
    6 Scenario: List 2 files in a directory
    7 Given I am in a directory "test"
    8 And I have a file named "foo"
    9 And I have a file named "bar"
    10 When I run "ls"
    11 Then I should get:
    12 """
    13 bar
    14 foo
    15 """
    12年11月3⽇日星期六

    View Slide

  34. Feature: ls
    In order to see the directory structure
    As a UNIX user
    I need to be able to list the current directory's contents
    Scenario: List 2 files in a directory # features/ls.feature:6
    Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    1 scenario (1 undefined)
    5 steps (5 undefined)
    0m0.019s
    12年11月3⽇日星期六

    View Slide

  35. You can implement step definitions for undefined
    steps with these snippets:
    /**
    * @Given /^I am in a directory "([^"]*)"$/
    */
    public function iAmInADirectory($arg1)
    {
    throw new PendingException();
    }
    /**
    * @Then /^I should get:$/
    */
    public function iShouldGet(PyStringNode $string)
    {
    throw new PendingException();
    }
    12年11月3⽇日星期六

    View Slide

  36. Feature: ls
    In order to see the directory structure
    As a UNIX user
    I need to be able to list the current directory's contents
    Scenario: List 2 files in a directory # features/ls.feature:6
    Given I am in a directory "test" # FeatureContext::iAmInADirectory()
    TODO: write pending definition
    And I have a file named "foo" # FeatureContext::iHaveAFileNamed()
    And I have a file named "bar" # FeatureContext::iHaveAFileNamed()
    When I run "ls" # FeatureContext::iRun()
    Then I should get: # FeatureContext::iShouldGet()
    """
    bar
    foo
    """
    1 scenario (1 pending)
    5 steps (4 skipped, 1 pending)
    0m0.018s
    12年11月3⽇日星期六

    View Slide

  37. FeatureContext::iAmInADirectory()
    37 /**
    38 * @Given /^I am in a directory "([^"]*)"$/
    39 */
    40 public function iAmInADirectory($dir)
    41 {
    42 $tmpFile = tempnam(sys_get_temp_dir(),
    '.placeholder');
    43 $tmpDir = dirname($tmpFile) . "/$dir";
    44 $this->dir = $tmpDir;
    45
    46 if (!file_exists($tmpDir)) {
    47 mkdir($tmpDir);
    48 }
    49
    50 chdir($tmpDir);
    51 }
    12年11月3⽇日星期六

    View Slide

  38. FeatureContext::iHaveAFileNamed()
    53 /**
    54 * @Given /^I have a file named "([^"]*)"$/
    55 */
    56 public function iHaveAFileNamed($file)
    57 {
    58 touch($this->dir . "/$file");
    59 }
    12年11月3⽇日星期六

    View Slide

  39. FeatureContext::iRun()
    61 /**
    62 * @When /^I run "([^"]*)"$/
    63 */
    64 public function iRun($command)
    65 {
    66 exec($command, $output);
    67 $this->output = trim(implode("\n", $output));
    68 }
    12年11月3⽇日星期六

    View Slide

  40. FeatureContext::iShouldGet
    70 /**
    71 * @Then /^I should get:$/
    72 */
    73 public function iShouldGet(PyStringNode $string)
    74 {
    75 if (strval($string) !== $this->output) {
    76 throw new Exception("Actual output is:
    \n". $this->output);
    77 }
    78 }
    12年11月3⽇日星期六

    View Slide

  41. $ behat
    Feature: ls
    In order to see the directory structure
    As a UNIX user
    I need to be able to list the current directory's contents
    Scenario: List 2 files in a directory
    Given I am in a directory "test"
    And I have a file named "foo"
    And I have a file named "bar"
    When I run "ls"
    Then I should get:
    """
    bar
    foo
    """
    1 scenario (1 passed)
    5 steps (5 passed)
    0m0.03s
    12年11月3⽇日星期六

    View Slide

  42. More...
    12年11月3⽇日星期六

    View Slide

  43. Behat Hooks
    12年11月3⽇日星期六

    View Slide

  44. Tags
    @billing
    Feature: Verify billing
    @important
    Scenario: Missing product description
    @bicker @annoy
    Scenario: Several products
    Only execute the features or scenarios
    with tags matching tag filter expression
    12年11月3⽇日星期六

    View Slide

  45. Tables
    Scenario:
    Given the following people exist:
    | name | email | phone |
    | Aslak | [email protected] | 123 |
    | Joe | [email protected] | 234 |
    | Bryan | [email protected] | 456 |
    12年11月3⽇日星期六

    View Slide

  46. Tables (code)
    /**
    * @Given /the following people exist:/
    */
    public function thePeopleExist(TableNode $table)
    {
    $hash = $table->getHash();
    foreach ($hash as $row) {
    // $row['name'], $row['email'], $row['phone']
    }
    }
    12年11月3⽇日星期六

    View Slide

  47. Placeholder
    Scenario Outline: controlling order
    Given there are cucumbers
    When I eat cucumbers
    Then I should have cucumbers
    Examples:
    | start | eat | left |
    | 12 | 5 | 7 |
    | 5 | 3 | 2 |
    12年11月3⽇日星期六

    View Slide

  48. Behat Extension
    • Mink - Web acceptance testing
    • Phabric - A DB mockup / fixture creation
    • Symfony2 - Integration for Symfony
    • Behatch - provides most common context
    http://extensions.behat.org/
    12年11月3⽇日星期六

    View Slide

  49. Demo
    https://github.com/Gasol/practical-behat
    12年11月3⽇日星期六

    View Slide

  50. References
    • http://behat.org/
    • http://cukes.info/
    • http://dannorth.net/introducing-bdd/
    • http://dannorth.net/whats-in-a-story/
    • https://speakerdeck.com/everzet/behat-by-
    example
    12年11月3⽇日星期六

    View Slide

  51. 12年11月3⽇日星期六

    View Slide

  52. Thanks
    12年11月3⽇日星期六

    View Slide

  53. Question?
    12年11月3⽇日星期六

    View Slide

  54. WE’RE HIRING
    12年11月3⽇日星期六

    View Slide