从 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)