gorghoa/scenariostate-behat-extension

此包已被弃用且不再维护。未建议替代包。

Behat 的场景共享状态扩展

安装次数: 598,124

依赖者: 1

建议者: 0

安全: 0

星标: 33

关注者: 3

分支: 6

开放问题: 5

类型:behat-extension

v1.0.7 2020-10-07 08:21 UTC

README

Build Status Scrutinizer Code Quality Code Coverage

⚠️ 此项目不再维护。不过,任何有兴趣接管的人都可以尝试 :).

何时使用

Behat 场景全都是关于状态的。首先,通过 Given 步骤将系统置于测试的特殊状态。然后,通过 When 步骤继续操作您的系统,最后通过 Then 步骤测试最终状态。

当测试一个像单页应用或状态网站的系统时,步骤的结果状态由系统本身(无论是浏览器、PHP 会话等)处理。

但是,当您测试一个无状态系统,尤其是 API 时,步骤的结果状态无人处理。这就是此扩展的情况。

安装

composer require --dev gorghoa/scenariostate-behat-extension @RC

然后更新项目的 behat.yml 配置文件,通过加载扩展

default:
    extensions:
        Gorghoa\ScenarioStateBehatExtension\ServiceContainer\ScenarioStateExtension: ~

使用

此 Behat 扩展将允许场景步骤提供和消费我所说的结果状态的“片段”。

每个场景都拥有自己的隔离且唯一的状态。

假设有一个这样的特性

    Feature: Monkey gathering bananas

        Scenario: Monkey gives a banana to another monkey
            When bonobo takes a banana
            And bonobo gives this banana to "gorilla"

看到“这个香蕉”了吗?在第二步执行期间,我们想要的正是猴子最初拿到的那个香蕉的引用。此 Behat 扩展将帮助我们传播香蕉引用到各个步骤中。

提供状态片段

要与其他场景的步骤共享状态的一部分,您的上下文需要实现 Gorghoa\ScenarioStateBehatExtension\Context\ScenarioStateAwareContext 接口。

此接口声明了一个实现方法:public function setScenarioState(ScenarioStateInterface $scenarioState),可以使用 ScenarioStateAwareTrait 导入。此 ScenarioState 负责存储您的状态。

use Gorghoa\ScenarioStateBehatExtension\Context\ScenarioStateAwareContext;
use Gorghoa\ScenarioStateBehatExtension\Context\ScenarioStateAwareTrait;
use Gorghoa\ScenarioStateBehatExtension\ScenarioStateInterface;

class FeatureContext implements ScenarioStateAwareContext
{
    use ScenarioStateAwareTrait;
}

然后,您可以通过 ScenarioStateInterface::provideStateFragment(string $key, mixed $value) 方法发布状态片段。

/**
 * @When bonobo takes a banana
 */
public function takeBanana()
{
    $banana = 'Yammy Banana';
    $bonobo = new Bonobo('Gerard');

    // Here, the banana `Yammy Banana` is shared amongst steps through the key "scenarioBanana"
    $this->scenarioState->provideStateFragment('scenarioBanana', $banana);

    // Here, the bonobo Gerard is shared amongst steps through the key "scenarioBonobo"
    $this->scenarioState->provideStateFragment('scenarioBonobo', $bonobo);
}

消费状态片段

要消费提供给场景状态的状态片段,您必须在步骤的方法中使用 ScenarioStateArgument 注解添加所需参数。它可以很容易地使用

  • 使用与存储中完全相同的名称注入参数:@ScenarioStateArgument("scenarioBanana")@ScenarioStateArgument(name="scenarioBanana")
  • 使用更改名称的参数从存储中注入:@ScenarioStateArgument(name="scenarioBanana", argument="banana")
use Gorghoa\ScenarioStateBehatExtension\Annotation\ScenarioStateArgument;

/**
 * @When bonobo gives this banana to :monkey
 *
 * @ScenarioStateArgument("scenarioBanana")
 * @ScenarioStateArgument(name="scenarioBonobo", argument="bonobo")
 *
 * @param string $monkey
 * @param string $scenarioBanana
 * @param Bonobo $bonobo
 */
public function giveBananaToGorilla($monkey, $scenarioBanana, Bonobo $bonobo)
{
    // (note that PHPUnit is here only given as an example, feel free to use any asserter you want)
    \PHPUnit_Framework_Assert::assertEquals($monkey, 'gorilla');
    \PHPUnit_Framework_Assert::assertEquals($scenarioBanana, 'Yammy Banana');
    \PHPUnit_Framework_Assert::assertEquals($bonobo->getName(), 'Gerard');
}

在 Behat 钩方法中使用状态片段

还可以在钩方法(BeforeScenario & AfterScenario)中消费状态片段。更好的是,顺序并不重要,您可以根据自己的意愿设置参数的顺序。

use Behat\Behat\Hook\Scope\AfterScenarioScope;
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
use Gorghoa\ScenarioStateBehatExtension\Annotation\ScenarioStateArgument;

/**
 * @BeforeScenario
 *
 * @ScenarioStateArgument("scenarioBanana")
 *
 * @param string              $scenarioBanana
 * @param BeforeScenarioScope $scope
 */
public function checkBananaBeforeScenario($scenarioBanana, BeforeScenarioScope $scope)
{
    // (note that PHPUnit is here only given as an example, feel free to use any asserter you want)
    \PHPUnit_Framework_Assert::assertEquals($scenarioBanana, 'Yammy Banana');
    \PHPUnit_Framework_Assert::assertNotNull($scope);
}

/**
 * @AfterScenario
 *
 * @ScenarioStateArgument("scenarioBanana")
 *
 * @param string             $scenarioBanana
 * @param AfterScenarioScope $scope
 */
public function checkBananaAfterScenario($scenarioBanana, AfterScenarioScope $scope)
{
    // (note that PHPUnit is here only given as an example, feel free to use any asserter you want)
    \PHPUnit_Framework_Assert::assertEquals($scenarioBanana, 'Yammy Banana');
    \PHPUnit_Framework_Assert::assertNotNull($scope);
}

为什么通过方法参数注入状态片段

  1. 为步骤方法明确依赖声明
  2. PHP运行时检查:如果参数不存在或不匹配类型提示,则快速失败
  3. 消耗共享场景状态的更简洁方式