從 Behat 開始

Behat 提供 Gherkin Syntax ,這是一種人類可讀的格式。它允許你輕鬆描述你的使用者故事。

要從 Behat 開始,你應該使用 Composer 安裝它,然後初始化你的測試檔案:

$ composer require --dev behat/behat="^3.0.5"

$ ./vendor/bin/behat --init

+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

預設情況下,你將測試檔案放在 features/資料夾中,並使用副檔名 .feature

每個測試檔案都應定義應用程式的特定功能。功能被分解為一系列場景,幷包含一系列需要成功執行以使場景通過的步驟。每個場景都需要傳遞才能傳遞一個功能。

# features/PartyHarmony.feature
Feature: Party Harmony
    As a Dungeon Master, I want to ensure harmony and mutual trust, so that
    the party can work together as a team

    Scenario: Teach members to respect each others property
        Given that the Wizard has 10 cookies
        And the Bard eats 1 cookie
        Then the Bard is mysteriously on fire

要執行測試,請直接執行 Behat 二進位制檔案。我們可以選擇指定要執行的功能檔案(否則執行所有測試)。此功能檔案將因未定義的步驟錯誤而失敗(因為我們尚未定義這些步驟的含義):

$ ./vendor/bin/behat features/PartyHarmony.feature
Feature: Party Harmony
    As a Dungeon Master, I want to ensure harmony and mutual trust, so that
    the party can work together as a team

  Scenario: Teach members to respect each others property # features/PartyHarmony.feature:6
    Given that the Wizard has 10 cookies
    And the Bard eats 1 cookie
    Then the Bard is mysteriously on fire

1 scenario (1 undefined)
3 steps (3 undefined)
0m0.01s (10.49Mb)

--- FeatureContext has missing steps. Define them with these snippets:

    /**
     * @Given that the Wizard has :arg1 cookies
     */
    public function thatTheWizardHasCookies($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Given the Bard eats :arg1 cookie
     */
    public function theBardEatsCookie($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then the Bard is mysteriously on fire
     */
    public function theBardIsMysteriouslyOnFire()
    {
        throw new PendingException();
    }

場景中的每個步驟都從上下文 PHP 檔案執行一段程式碼(不同的功能測試可以載入不同的上下文)。我們可以複製 Behat 建議的例子或建立我們自己的例子。該步驟與正規表示式檢查匹配。所以,如果我們實施

<?php
# 
class FeatureContext {
    /**
     * @Given that the wizard has :num cookies
     */
    public function wizardHasCookies($num) {
        // $this->wizard is a pre-existing condition.... like syphilis
        $this->wizard->setNumberOfCookies($num);
    }

    /**
     * @Given the Bard eats :num cookie
     */
    public function theBardEatsCookie($num)
    {
        $this->bard->consumeCookies($num);
    }

    /**
     * @Then the Bard is mysteriously on fire
     */
    public function theBardIsMysteriouslyOnFire() {
        PHPUnit_Framework_Assert::assertTrue(
            $this->bard->isBardOnFire()
        );
    }
}

你會注意到 PHPUnit_Framework_Assert 的使用。Behat 沒有它自己的斷言系統,所以你可以使用你想要的任何一個。

現在執行測試將執行實際程式碼,我們可以測試是否所有內容都通過:

$ ./vendor/bin/behat features/PartyHarmony.feature
Feature: Party Harmony
    As a Dungeon Master, I want to ensure harmony and mutual trust, so that
    the party can work together as a team

  Scenario: Teach members to respect each others property # features/PartyHarmony.feature:6
    Given that the Wizard has 10 cookies                  # FeatureContext::thatTheWizardHasCookies()
    And the Bard eats 1 cookie                            # FeatureContext::theBardEatsCookie()
    Then the Bard is mysteriously on fire                 # FeatureContext::theBardIsMysteriouslyOnFire()

1 scenario (1 passed)
3 steps (3 passed)
0m0.01s (10.59Mb)