You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pytest-bdd中YAML数据加载时步骤定义未找到的原因排查

pytest-bdd Scenario Outline 出现 StepDefinitionNotFoundError 的原因及解决方法

错误根源

问题核心是Feature文件中的步骤文本与步骤定义的装饰器文本不匹配:

  • Feature里的When步骤写了:When I enter my login and "<password>",参数被双引号包裹
  • 当Scenario Outline替换Examples中的参数后,实际执行的步骤文本变成了:I enter my login and "PASSWORD1"
  • 但你的步骤定义装饰器是:@when('I enter my login and <password>'),没有包含双引号,导致pytest-bdd无法找到对应的步骤实现。

解决方法

两种可行修正方式,选其一即可:

方式一:修改Feature文件,移除参数的双引号

将Feature中的When步骤改为:

When I enter my login and <password>

方式二:修改步骤定义的装饰器,匹配双引号

将@when装饰器的文本改为包含双引号的版本:

@when('I enter my login and "<password>"')
def step_when_enter_credentials(webdriver_initializer, password):
    driver = webdriver_initializer
    selenium_elements = Page(driver)
    globals_instance = Globals(PARAMS_PATH)
    password_to_use = globals_instance.get_yaml_element(password)
    selenium_elements.type_into(selenium_elements.EMAIL_ADDRESS_REGISTER_VALUE, selenium_elements.globals.EMAIL1)
    selenium_elements.type_into(selenium_elements.EMAIL_PASSWORD, password_to_use)

额外优化建议

每次在步骤里实例化Globals(PARAMS_PATH)会重复加载YAML文件,建议把Globals做成pytest fixture提升执行效率:

import pytest
import yaml

@pytest.fixture(scope="session")
def globals_fixture():
    class Globals:
        def __init__(self, path):
            self.load_data_from_yaml(path)
        
        def load_data_from_yaml(self, path):
            with open(path, "r") as param_file:
                try:
                    yaml_file = yaml.safe_load(param_file)
                    self.TITLE = yaml_file.get("title1")
                    self.USERNAME1 = yaml_file.get("username1")
                    self.PASSWORD1 = yaml_file.get("password1")
                    self.WRONG_PASSWORD = yaml_file.get("wrong_password")
                    self.LAST_NAME1 = yaml_file.get("lastname1")
                    self.EMAIL1 = yaml_file.get("email1")
                    self.BDAY = yaml_file.get("bday")
                    self.BMONTH = yaml_file.get("bmonth")
                    self.BYEAR = yaml_file.get("byear")
                except yaml.YAMLError as exc:
                    print(exc)
        
        def get_yaml_element(self, element):
            return getattr(self, element, None)
    
    return Globals(PARAMS_PATH)

之后在步骤里直接使用该fixture:

@when('I enter my login and <password>')
def step_when_enter_credentials(webdriver_initializer, password, globals_fixture):
    driver = webdriver_initializer
    selenium_elements = Page(driver)
    password_to_use = globals_fixture.get_yaml_element(password)
    selenium_elements.type_into(selenium_elements.EMAIL_ADDRESS_REGISTER_VALUE, globals_fixture.EMAIL1)
    selenium_elements.type_into(selenium_elements.EMAIL_PASSWORD, password_to_use)

内容的提问来源于stack exchange,提问作者Bart77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:45:09