Python Behave如何定义同名步骤以避免AmbiguousStep异常?
概述
在Python Behave中,有没有方法可以避免因需要多次使用相同步骤名称而触发的异常?
需求说明
我在使用Python Behave时需要定义两个同名步骤,我的项目结构如下:
./features customers.features products.features ./steps customers.py products.py
我希望下方定义的步骤可以同时在customers.features和products.features中使用:
@when('we implement a test') def step_impl(context): assert True is not False
问题现象
当我尝试上述配置时,运行测试会抛出behave.step_registry.AmbiguousStep异常。我原本以为customer.features只会调用customers.py中定义的步骤、products.features只会调用products.py中定义的步骤,但实际运行逻辑并非如此。
除了将步骤分别改写为@when('we implement a test 1')和@when('we implement a test 2')之外,有没有其他解决方案?
已尝试方案
我在排查问题的过程中,看到可以按如下方式排布项目文件,但我尝试后Behave无法识别到任何步骤。
结合我的示例场景,对应的项目结构如下:
./features ./customers customers.features ./steps customers.py ./products products.features ./steps products.py
但我按该结构配置后运行测试,无法识别到任何定义的步骤。
核心问题
有没有方案可以避免因需要多次使用相同步骤名称而出现的步骤命名冲突问题?
解决方案
Behave的步骤默认是全局注册的,只要在steps目录下的所有步骤定义都会被全局加载,因此同名步骤会触发冲突,可通过以下几种方案解决:
- 方案1:抽取公共步骤
如果你两个步骤的实现逻辑完全相同,不需要在两个py文件中重复定义,直接将该步骤放在steps目录下的公共文件(比如common.py)中即可,两个feature文件都可以正常调用该步骤,不会触发冲突。 - 方案2:开启步骤目录作用域配置
你尝试的分目录结构没有生效,是因为没有开启对应的配置项。只需要在项目根目录的behave.ini配置文件中添加如下配置:
开启该配置后,每个子feature目录下的steps只会被对应目录下的feature文件加载,不会全局注册,同名步骤不会互相干扰。[behave] steps_are_scoped_to_feature_dir = True - 方案3:使用参数化步骤区分逻辑
如果你两个同名步骤的实现逻辑不同,可以将步骤定义为参数化形式,根据参数值走不同逻辑,示例如下:
在feature文件中分别写@when('we implement a {scene} test') def step_impl(context, scene): if scene == "customer": # 客户场景逻辑 assert True is not False elif scene == "product": # 产品场景逻辑 assert 1 == 1when we implement a customer test和when we implement a product test即可。 - 方案4:通过场景标签区分逻辑
也可以在feature文件中给不同场景添加对应标签,在步骤实现中通过标签判断走对应逻辑:@when('we implement a test') def step_impl(context): if "customer" in context.scenario.tags: # 客户场景逻辑 pass elif "product" in context.scenario.tags: # 产品场景逻辑 pass
内容的提问来源于stack exchange,提问作者shearichard
相关产品推荐
相关产品推荐

