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

时间:2013-03-18 08:38:03

标签: behat

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

目前我有

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

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

在功能上下文中,我告诉我们SpecialTestContext作为子上下文。

当我运行测试时,抱怨

  

[贝哈特\贝哈特\异常\ RedundantException]
  步骤“/ ^ testScenarioExists $ /”已在SpecialTestContext中定义:: aTestscenarioexists()

有人可以指出我正确的方向吗?

为了进一步说明我为什么要尝试实现这一点,我想要实现的是能够运行具有不同环境的场景,并在gherkin文件中指定环境,例如:

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

然后我可以在FeatureContext中添加一些代码来加载正确的子上下文。

3 个答案:

答案 0 :(得分: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";
    }
}

答案 1 :(得分:4)

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

在动态加载子上下文时,这是不可能的:

  1. 子编辑在“编译时”加载 - 即。在主要的FeatureContext构造函数
  2. 当第一步定义运行时,behat已经收集了所有注释并将它们映射到步骤定义,不再可以/应该添加
  3. 检查一下以了解Context的行为: http://docs.behat.org/guides/4.context.html#contexts-lifetime

    要考虑更广泛的事情:

    1. 非开发人员(或者至少是没有编写系统的开发人员)必须能够理解在小黄瓜场景中捕获的任何东西。一个场景应该传达完整的,一个(理想情况下不再是)业务规则,而不必深入研究任何代码

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

    3. 这取决于您如何组织FeatureContexts,但是您希望通过系统中的主题/域来执行此操作,例如:

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

答案 2 :(得分:0)

无法使用相同的句子定义过度使用的方法。

class SpecialTestContext extends TestContext {

  public function aTestscenarioexists() {
    echo "I am a special test scenario\n";
  }
}