为什么 ActiveTagMatcher 忽略了我传递给它的一些值?

Why is ActiveTagMatcher is ignoring some of the values I'm passing to it?

我已经成功地使用 ActiveTagMatcher 标记了一些在某些情况下应该是 运行 的测试,但是由于某些原因 ActiveTagMatcher 忽略了我设置的一些值。我把它归结为这个例子:

features/test.feature:

Feature: foo

# This does not work!
@only.with_variable_one=True
Scenario: variable one must be True
  Then something

# This works fine.
@only.with_variable_two=foo
Scenario: variable two must be foo
  Then something

# Try to see if shortening it to something that does not use the `=` works.
# It does not work either.  
@only.with_variable_one
Scenario: variable two must be foo
  Then something

features/environment.py:

import os

from behave.tag_matcher import ActiveTagMatcher

def before_all(context):
    condition = context.config.userdata.get("condition", None) is not None
    values = {
        "variable_one": condition,
        "variable_two": "foo"
    }
    context.active_tag_matcher = ActiveTagMatcher(values)

def before_scenario(context, scenario):
    if context.active_tag_matcher.should_exclude_with(scenario.effective_tags):
        scenario.skip(reason="Disabled by an active tag")
        return

我有一个 features/steps/something.py,其中包含的内容刚好足以避免有关步骤未定义的投诉:

@then(u"something")
def step_impl(context):
    pass

运行 behave 只有在我不使用 -D condition 调用它时才应该跳过第一个场景, 但它总是跳过第一个场景! 反之就是从不跳过最后一个场景!

我正在使用 Behave 1.2.5。

快速回答

确保 values 字典中的所有值都是字符串:

values = {
    "variable_one": str(condition),
    "variable_two": "foo"
}

并且 @only.with_variable_one 你最后一个场景 不能 工作。您必须有一个 equal-sign 和一个标签值才能与 ActiveTagMatcher.

一起使用

更长的解释

让我们从简单的部分开始。标签 @only.with_variable_one 根本无法被 ActiveTagMacher 识别。存在其他不需要使用运算符来指示如果它们对应的条件为真则它们应该处于活动状态的标签。例如,当您想使用 Behave 的内置 work-in-progress 功能时,您可以写 @wip,而不是 @wip=True。但是,ActiveTagMacher 要求你使用的标签中有等号,否则无法识别。所以 @only.with_variable_one 完全被忽略了。

@only.with_variable_one=True 对您不起作用的原因是因为 ActiveTagMatcher 对标记的解析将导致将 True 读取为字符串 "True" 而在您的values 字典你传递一个布尔值TrueActiveTagMacher 使用 operator.eq 检查是否相等。所以测试执行等同于 "True" == True,这在 Python 中是错误的。所以相等性检查总是失败,因此 ActiveTagMacher 总是排除你的场景。您可以通过将布尔值转换为字符串来解决此问题:

values = {
    "variable_one": str(condition),
    "variable_two": "foo"
}

事实上,values 字典中的每个值都必须是一个字符串。例如,如果你有一个数字,你还必须将它转换成一个字符串。否则,针对该数字执行的测试将永远不会为真。