gorghoa / scenariostate-behat-extension
Behat 的场景共享状态扩展
Requires
- php: >=5.5
- behat/behat: ^3.0.12
- doctrine/annotations: ^1.2
- symfony/dependency-injection: ^2.7|^3.0|^4.0|^5.0
- symfony/process: ^2.0|^3.0|^4.0|^5.0
Requires (Dev)
- phpspec/phpspec: ~2.0
- phpunit/phpunit: ~4.5
- dev-master
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.0
- v1.0.0-rc.3
- v1.0.0-rc.2
- v1.0.0-rc.1
- dev-allow-php5-to-fail-on-build
- dev-deprecate-php5
- dev-30-going-to-events
- dev-research/30-decoupling
- dev-feat/composer-version
- dev-fix/coding-standards--14
- dev-fix/readme-typo
- dev-feat/scrutinizr
- dev-fix/updatecopyright
- dev-feat/update-readme
This package is not auto-updated.
Last update: 2022-07-30 02:04:17 UTC
README
⚠️ 此项目不再维护。不过,任何有兴趣接管的人都可以尝试 :).
何时使用
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); }
为什么通过方法参数注入状态片段
- 为步骤方法明确依赖声明
- PHP运行时检查:如果参数不存在或不匹配类型提示,则快速失败
- 消耗共享场景状态的更简洁方式