Behave中多场景共享带Examples的Background实现咨询
Behave共享参数化Background的解决方案
你当前的写法不生效是因为Behave原生不支持Feature级别的Examples——Examples只能绑定到单个Scenario Outline,没法直接给整个Feature的所有场景提供参数化的前置逻辑。下面给两种可行的解决办法:
方案一:用Scenario Outline复用参数(原生直接实现)
把每个测试场景改成Scenario Outline,然后在Feature末尾放共用的Examples表格。虽然每个场景都要写,但避免了重复的Background配置,可读性也不错。
示例Feature文件:
Feature: Car Scenario Outline: Can drive Given a <car_type> has entered the assembly line When the wheels are added to the car Then it can drive Scenario Outline: Can honk Given a <car_type> has entered the assembly line When a horn is added to the car Then it can honk # 所有场景共用这组参数 Examples: | car_type | | truck | | van |
你可以把Given a <car_type> has entered the assembly line这个步骤在steps文件里实现一次,所有场景直接复用逻辑就行。
方案二:用环境钩子实现全局参数化前置(更优雅)
通过environment.py的钩子函数,自动给所有场景遍历指定参数,执行前置逻辑,不用改每个场景的结构。
步骤1:修改Feature文件,加标签标记参数
Feature: Car @parametrize_car_types=truck,van Scenario: Can drive When the wheels are added to the car Then it can drive Scenario: Can honk When a horn is added to the car Then it can honk
步骤2:编写environment.py的钩子逻辑
from behave.model_core import Status from behave.runner import Context def get_car_types_from_tag(tag): # 解析标签里的参数,比如从@parametrize_car_types=truck,van里提取列表 _, values = tag.split('=', 1) return [val.strip() for val in values.split(',')] def run_scenario_with_car_type(context, scenario, car_type): # 把当前车型存到上下文,供后续步骤用 context.car_type = car_type # 执行原来Background里的前置步骤 context.execute_steps(f'Given a {car_type} has entered the assembly line') # 执行场景本身的步骤 scenario.run(context) @before_scenario def setup_parametrized_background(context: Context, scenario): # 找Feature上的参数化标签 parametrize_tags = [t for t in scenario.feature.tags if t.startswith('@parametrize_car_types=')] if not parametrize_tags: return car_types = get_car_types_from_tag(parametrize_tags[0]) if not car_types: return # 标记已处理,防止重复执行 if hasattr(context, '_param_handled'): return # 遍历每个车型,重新执行场景 for car_type in car_types: new_context = context.copy() run_scenario_with_car_type(new_context, scenario, car_type) # 如果有一个实例失败,标记整个场景为失败 if new_context.scenario.status == Status.failed: scenario.status = Status.failed # 跳过原场景的默认执行 scenario.skip()
步骤3:在步骤文件里使用参数
from behave import given, when, then @given('a {car_type} has entered the assembly line') def step_impl(context, car_type): # 这里写实际的初始化逻辑,比如创建对应车型的实例 context.car = create_car_instance(car_type) @when('the wheels are added to the car') def step_impl(context): context.car.install_wheels() @then('it can drive') def step_impl(context): assert context.car.is_drivable is True # 鸣笛步骤同理
这样每个场景都会自动遍历truck和van两种类型,执行对应的前置操作和测试步骤,不用每个场景都写Scenario Outline。
内容的提问来源于stack exchange,提问作者Sabrina Leggett
相关产品推荐
相关产品推荐

