python 行为中针对不同步骤名称显示的不明确步骤异常
Ambiguous Step exception shown for different step names in python behave
我在 steps 目录下有两个不同的 python 文件:
driverlogon.py 和
triplogon.py
driverlogon.py 定义步骤
@when(u'enter the {driver_id}')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
triplogon.py 定义步骤
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.enter_block(context.block)
当我运行这个程序时,我得到以下错误信息
在这种情况下,它们有不同的文本,甚至函数的内容也不同。
为什么会这样,谁能帮我理解这个?提前致谢
Exception AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\Lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Program Files (x86)\Python\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Program Files (x86)\Python\Scripts\behave.exe\__main__.py", line 7, in <module>
File "c:\program files (x86)\python\lib\site-packages\behave\__main__.py", line 183, in main
return run_behave(config)
File "c:\program files (x86)\python\lib\site-packages\behave\__main__.py", line 127, in run_behave
failed = runner.run()
File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 804, in run
return self.run_with_paths()
File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 809, in run_with_paths
self.load_step_definitions()
File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 796, in load_step_definitions
load_step_modules(step_paths)
File "c:\program files (x86)\python\lib\site-packages\behave\runner_util.py", line 412, in load_step_modules
exec_file(os.path.join(path, name), step_module_globals)
File "c:\program files (x86)\python\lib\site-packages\behave\runner_util.py", line 386, in exec_file
exec(code, globals_, locals_)
File "steps\triplogon.py", line 23, in <module>
@when(u'enter the configured block number')
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 92, in wrapper
self.add_step_definition(step_type, step_text, func)
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 58, in add_step_definition
raise AmbiguousStep(message % (new_step, existing_step))
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
步骤定义的工作方式如下:
- 你新建一个py文件
- 您向该文件添加了一个新的函数定义
- 在这种情况下,您的两个文件具有相同的函数名称,
def step_impl
- 您使用想要与之关联的功能文件文本装饰您的新功能
enter the {driver_id}
enter the configured block number
- 当您 运行 行为时,程序会收集其所有特征文件及其所有步骤定义,然后尝试将两者相关联
- 对于上面的示例,Behave 找到文本
enter the {driver_id}
,并将其与函数 step_impl
相关联
- 然后 Behave 找到文本
enter the configured block number
,并尝试将其与其函数定义相关联,但发现函数 step_impl
已被定义并与特征文本相关联。不知道该怎么做,Behave 抛出 AmbiguousStep
异常让你知道函数名称已被使用两次。
要解决此问题,您需要确保您的函数名称在所有步骤定义文件中都是唯一的。因此,在您的情况下,您有两个文件,每个文件都定义了一个名为 step_impl
的函数。您应该做的是用唯一名称重命名这些函数,以便 Behave 可以在 运行 时间正确关联这些名称。为确保名称是唯一的,我建议选择与装饰文本紧密匹配的名称。如果是我写这些定义,我会重写如下:
driverlogon.py
@when(u'enter the {driver_id}')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
triplogon.py
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.block_data(context.block)
编辑#1:
感谢您包含堆栈跟踪。由此看来,您在两个不同的文件中两次定义了相同的步骤:
File "steps\triplogon.py", line 23, in <module>
@when(u'enter the configured block number')
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 92, in wrapper
self.add_step_definition(step_type, step_text, func)
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 58, in add_step_definition
raise AmbiguousStep(message % (new_step, existing_step))
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
您会注意到最上面一行写着:
File "steps\triplogon.py", line 23, in <module>
@when(u'enter the configured block number')
表示步骤enter the configured block number
定义在triplogon.py
然后跟踪的最后一行说:
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
表示在driverlogon.py
中也定义了enter the configured block number
确保仅在两个文件之一中定义了该步骤。
如果您想保留这些名称,可以这样写:
driverlogon.py
@when(u'enter the "{driver_id}"')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
triplogon.py
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.block_data(context.block)
在这种情况下不会引发异常,但 driver_id 将作为字符串传递,步骤如下所示:
When enter the "10"
但是,如果您希望它被解析为 int 而不是您可以使用预定义的数据类型 d
在这种情况下如下所示:
@when(u'enter the "{driver_id:d}"')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
https://behave.readthedocs.io/en/latest/parse_builtin_types.html
尽管@automationleg 的答案在这种特殊情况下可能是正确的,但歧义问题来自另一个方向,并不能总是通过使用双引号来解决。歧义可能仍然存在。
查看此工单了解详情:https://github.com/behave/behave/issues/435。
正确的解决方案是对参数使用类型模式,否则将使用所有格解析器并尽可能多地消耗 - 为所谓的重复留出空间。
谢谢@Janos。
我将在此处提取 behave
issue 结果以总结解决方案。
将类型说明符添加到参数(例如 :S 或 :d)
@when(u'enter the {driver_id:S}')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.enter_block(context.block)
先放更复杂(更长?)的定义。所以如果你把它放在一个文件中,它将是:
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.enter_block(context.block)
@when(u'enter the {driver_id}')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
或者检查重命名文件是否有效,定义更复杂的文件是否按字母顺序排列在另一个文件之前。
我在 steps 目录下有两个不同的 python 文件: driverlogon.py 和 triplogon.py
driverlogon.py 定义步骤
@when(u'enter the {driver_id}')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
triplogon.py 定义步骤
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.enter_block(context.block)
当我运行这个程序时,我得到以下错误信息
在这种情况下,它们有不同的文本,甚至函数的内容也不同。
为什么会这样,谁能帮我理解这个?提前致谢
Exception AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
Traceback (most recent call last):
File "C:\Program Files (x86)\Python\Lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "C:\Program Files (x86)\Python\Lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Program Files (x86)\Python\Scripts\behave.exe\__main__.py", line 7, in <module>
File "c:\program files (x86)\python\lib\site-packages\behave\__main__.py", line 183, in main
return run_behave(config)
File "c:\program files (x86)\python\lib\site-packages\behave\__main__.py", line 127, in run_behave
failed = runner.run()
File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 804, in run
return self.run_with_paths()
File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 809, in run_with_paths
self.load_step_definitions()
File "c:\program files (x86)\python\lib\site-packages\behave\runner.py", line 796, in load_step_definitions
load_step_modules(step_paths)
File "c:\program files (x86)\python\lib\site-packages\behave\runner_util.py", line 412, in load_step_modules
exec_file(os.path.join(path, name), step_module_globals)
File "c:\program files (x86)\python\lib\site-packages\behave\runner_util.py", line 386, in exec_file
exec(code, globals_, locals_)
File "steps\triplogon.py", line 23, in <module>
@when(u'enter the configured block number')
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 92, in wrapper
self.add_step_definition(step_type, step_text, func)
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 58, in add_step_definition
raise AmbiguousStep(message % (new_step, existing_step))
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
步骤定义的工作方式如下:
- 你新建一个py文件
- 您向该文件添加了一个新的函数定义
- 在这种情况下,您的两个文件具有相同的函数名称,
def step_impl
- 在这种情况下,您的两个文件具有相同的函数名称,
- 您使用想要与之关联的功能文件文本装饰您的新功能
enter the {driver_id}
enter the configured block number
- 当您 运行 行为时,程序会收集其所有特征文件及其所有步骤定义,然后尝试将两者相关联
- 对于上面的示例,Behave 找到文本
enter the {driver_id}
,并将其与函数step_impl
相关联
- 然后 Behave 找到文本
enter the configured block number
,并尝试将其与其函数定义相关联,但发现函数step_impl
已被定义并与特征文本相关联。不知道该怎么做,Behave 抛出AmbiguousStep
异常让你知道函数名称已被使用两次。
要解决此问题,您需要确保您的函数名称在所有步骤定义文件中都是唯一的。因此,在您的情况下,您有两个文件,每个文件都定义了一个名为 step_impl
的函数。您应该做的是用唯一名称重命名这些函数,以便 Behave 可以在 运行 时间正确关联这些名称。为确保名称是唯一的,我建议选择与装饰文本紧密匹配的名称。如果是我写这些定义,我会重写如下:
driverlogon.py
@when(u'enter the {driver_id}')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
triplogon.py
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.block_data(context.block)
编辑#1:
感谢您包含堆栈跟踪。由此看来,您在两个不同的文件中两次定义了相同的步骤:
File "steps\triplogon.py", line 23, in <module>
@when(u'enter the configured block number')
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 92, in wrapper
self.add_step_definition(step_type, step_text, func)
File "c:\program files (x86)\python\lib\site-packages\behave\step_registry.py", line 58, in add_step_definition
raise AmbiguousStep(message % (new_step, existing_step))
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
您会注意到最上面一行写着:
File "steps\triplogon.py", line 23, in <module>
@when(u'enter the configured block number')
表示步骤enter the configured block number
定义在triplogon.py
然后跟踪的最后一行说:
behave.step_registry.AmbiguousStep: @when('enter the configured block number') has already been defined in
existing step @when('enter the {driver_id}') at steps/driverlogon.py:26
表示在driverlogon.py
enter the configured block number
确保仅在两个文件之一中定义了该步骤。
如果您想保留这些名称,可以这样写:
driverlogon.py
@when(u'enter the "{driver_id}"')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
triplogon.py
@when(u'enter the configured block number')
def step_enter_the_configured_block_number(context):
ByBlock.block_data(context.block)
在这种情况下不会引发异常,但 driver_id 将作为字符串传递,步骤如下所示:
When enter the "10"
但是,如果您希望它被解析为 int 而不是您可以使用预定义的数据类型 d
在这种情况下如下所示:
@when(u'enter the "{driver_id:d}"')
def step_enter_the_driver_id(context,driver_id):
SelectDriver.input_driver(driver_id)
https://behave.readthedocs.io/en/latest/parse_builtin_types.html
尽管@automationleg 的答案在这种特殊情况下可能是正确的,但歧义问题来自另一个方向,并不能总是通过使用双引号来解决。歧义可能仍然存在。
查看此工单了解详情:https://github.com/behave/behave/issues/435。
正确的解决方案是对参数使用类型模式,否则将使用所有格解析器并尽可能多地消耗 - 为所谓的重复留出空间。
谢谢@Janos。
我将在此处提取 behave
issue 结果以总结解决方案。
将类型说明符添加到参数(例如 :S 或 :d)
@when(u'enter the {driver_id:S}') def step_enter_the_driver_id(context,driver_id): SelectDriver.input_driver(driver_id) @when(u'enter the configured block number') def step_enter_the_configured_block_number(context): ByBlock.enter_block(context.block)
先放更复杂(更长?)的定义。所以如果你把它放在一个文件中,它将是:
@when(u'enter the configured block number') def step_enter_the_configured_block_number(context): ByBlock.enter_block(context.block) @when(u'enter the {driver_id}') def step_enter_the_driver_id(context,driver_id): SelectDriver.input_driver(driver_id)
或者检查重命名文件是否有效,定义更复杂的文件是否按字母顺序排列在另一个文件之前。