是否有可能在behat上下文中覆盖步骤定义?

use*_*503 10 behat

是否有可能让子上下文类扩展另一个子上下文并覆盖函数?

目前我有

class TestContext extends BehatContext {
    /**
     * @Given /^a testScenarioExists$/
     */
    public function aTestscenarioexists() {
        echo "I am a generic test scenario\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

class SpecialTestContext extends TestContext {
    /**
     * @Given /^a testScenarioExists$/
     */
    public function aTestscenarioexists() {
       echo "I am a special test scenario\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

在特征上下文中,我告诉它们SpecialTestContext作为子上下文.

当我运行测试behat抱怨

[Behat\Behat\Exception\RedundantException]
步骤"/ ^ testScenarioExists $ /"已在SpecialTestContext :: aTestscenarioexists()中定义

有人可以用这个指向我正确的方向吗?

为了让一些进一步的信息,为什么我试图做到这一点我想实现是运行与不同的环境场景,并在小黄瓜文件中指定的环境的能力,例如:

Scenario: Test with generic environment
Given I am in the environment "generic"
    And a test scenario exists

Scenario: Test with specialised environment
Given I am in the environment "specialised"
    And a test scenario exists
Run Code Online (Sandbox Code Playgroud)

然后我可以使用添加一些代码FeatureContext来加载正确的子上下文.

小智 10

正如Rob Squires所提到的,动态上下文加载将不起作用.

但我确实有一个替代步骤定义的解决方法,我经常使用. 不要注释您的方法.Behat将在超类中获取重写方法的注释,并将该方法名称映射到匹配步骤.找到匹配步骤后,将调用子类中的方法.为了说明这一点,我已经开始使用@override注释了.@override注释对Behat没有特殊意义.

class SpecialTestContext extends TestContext {
    /**
     * @override Given /^a testScenarioExists$/
     */
    public function aTestscenarioexists() {
       echo "I am a special test scenario\n";
    }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*res 4

简而言之......这是不可能的:http://docs.behat.org/guides/2.definitions.html#redundant-step-definitions

就动态加载子上下文而言,这是不可能的:

  1. 子上下文在“编译时”加载 - 即。在主要的FeatureContext构造函数中
  2. 当第一个步骤定义运行时,behat 已经收集了所有注释并将它们映射到步骤定义,不能/不应该添加更多

检查一下以了解Context行为方式: http://docs.behat.org/guides/4.context.html#contexts-lifetime

需要考虑一些更广泛的事情:

  1. 小黄瓜场景中捕获的任何内容都必须能够被非开发人员理解(或者至少是没有编写系统的开发人员!)。场景应该完整地传达一个(最好不再是)业务规则,而无需深入研究任何代码

  2. 您不想在步骤定义中隐藏太多逻辑,任何规则都应该在小黄瓜场景中捕获

  3. 这取决于您如何组织您的FeatureContexts,但是您将希望通过系统内的主题/域来做到这一点,例如:

    • aDatabaseContext可能关心读取+写入测试数据库
    • 可能ApiContext包含与验证系统中的 api 有关的步骤
    • 可能CommandContext关心验证您的系统控制台命令