向Behave方法添加公共属性

2024-05-15 17:32:23 发布

您现在位置:Python中文网/ 问答频道 /正文

使用了伟大的Behave框架,但我的OOP技能不足。在

behavior有一个内置的上下文命名空间,可以在测试执行步骤之间共享对象。在初始化WebDriver会话之后,我使用这个context在步骤之间传递它来保存所有内容。功能很好,但正如您在下面看到的,它不是干的。在

如何/在何处只能将这些属性添加到step_impl()context一次?在

环境.py

from selenium import webdriver

def before_feature(context, scenario):
    """Initialize WebDriver instance"""

    driver = webdriver.PhantomJS(service_args=service_args, desired_capabilities=dcap)

    """
    Do my login thing..
    """

    context.driver = driver
    context.wait = wait
    context.expected_conditions = expected_conditions
    context.xenv = env_data

步骤.py

^{pr2}$

Tags: py框架技能driverservicecontextargs步骤
3条回答

您可以定义一个修饰符,为您“解包”上下文并将“unpacked”值作为参数传递:

环境.py

def before_feature(context, feature):
    context.spam = 'spam'

def after_feature(context, feature):
    del context.spam

测试功能

^{pr2}$

步骤.py

def add_context_attrs(func):
    @functools.wraps(func)  # wrap it neatly
    def wrapper(context, *args, **kwargs):  # accept arbitrary args/kwargs
        kwargs['spam'] = context.spam  # unpack 'spam' and add it to the kwargs
        return func(context, *args, **kwargs)  # call the wrapped function
    return wrapper

@step('spam should be "{val}"')
@add_context_attrs
def assert_spam(context, val, spam):
    assert spam == val

首先,您可以跳过这个解包,在任何地方使用context属性,比如context.driver.get("http://domain.com")

如果您不喜欢它,并且您确实希望使用局部变量,可以使用元组解包来使代码稍微好一点:

import operator
def example_step(context):
    driver, xenv = operator.attrgetter('driver', 'xenv')(context)

您可以将这样的默认属性列表分解出来,但这会使整个过程有点含蓄:

^{pr2}$

如果你仍然不喜欢,你可以用globals()来捣乱。例如一个类似crate的函数:

def unpack(context, loc, field_list):
    for field in field_list:
        loc[field]  = getattr(context, field, None)

在你的步骤中使用它:

def example_step(context):
    unpack(context, globals(), ('driver', 'xenv'))

    # now you can use driver and xenv local variables
    driver.get('http://domain.com')

这将减少代码中的重复,但这是非常隐式的,可能很危险。所以不建议这样做。在

我只需要使用元组解包。它简单明了,所以不会引起额外的错误。在

相关问题 更多 >