如何在一个位置将一个值更改为另一个值并在几个函数中使用它?

时间:2019-05-09 04:53:36

标签: python bdd python-behave

我正在为BDD行为编写API的测试自动化。我需要在环境之间切换。有没有一种可能的方法可以在一个位置更改一个值而不将其添加到每个功能?示例:

我试图通过为每个函数增加值来做到这一点,但这会使所有项目变得非常复杂

headers = {
    'Content-Type': 'application/json',
    'country': 'fi'
}

我该如何将标头中的国家/地区值仅从“ fi”切换到“ es” 然后所有功能都应切换到es环境,例如

def sending_post_request(endpoint, user):
    url = fi_api_endpoints.api_endpoints_list.get(endpoint)
    personalId = {'personalId': user}
    json_post = requests.post(url,
                            headers=headers,
                            data=json.dumps(personalId)
                                )
    endpoint_message = json_post.text
    server_status = json_post.status_code

def phone_number(phone_number_status):
    if phone_number_status == 'wrong':
        cursor = functions_concerning_SQL_conection.choosen_db('fi_sql_identity')
        cursor.execute("SELECT TOP 1 PersonalId from Registrations where PhoneNumber is NULL")
        result = cursor.fetchone()
        user_with_no_phone_number = result[0]
        return user_with_no_phone_number
    else:
        cursor = functions_concerning_SQL_conection.choosen_db('fi_sql_identity')
        cursor.execute("SELECT TOP 1 PersonalId from Registrations where PhoneNumber is not NULL")
        result = cursor.fetchone()
        user_with_phone_number = result[0]
        return user_with_phone_number

当我将标题中的“ fi”更改为“ es”时,

fi_sql_identity change to es_sql_identity
url = fi_api_endpoints.api_endpoints_list.get(endpoint) change to 
url = es_api_endpoints.api_endpoints_list.get(endpoint)

谢谢,请帮忙

2 个答案:

答案 0 :(得分:1)

关于您的原始问题,此案的解决方案是closure

def f(x):
    def long_calculation(y):
        return x * y
    return long_calculation

# create different functions without dispatching multiple times
g = f(val_1)
h = f(val_2)

g(val_3)
h(val_3)

好吧,问题是为什么您要hardcode一切?通过此更新,您可以简化功能,例如:

def phone_number(phone_number_status, db_name='fi_sql_identity'):
    cursor = functions_concerning_SQL_conection.choosen_db(db_name)

    if phone_number_status == 'wrong':
        sql = "SELECT TOP 1 PersonalId from Registrations where PhoneNumber is NULL"
    else:
        sql = "SELECT TOP 1 PersonalId from Registrations where PhoneNumber is not NULL"

    cursor.execute(sql)
    result = cursor.fetchone()
    return result[0]

也请不要这样写:

# WRONG
fi_db_conn.send_data()

但是使用参数

region = 'fi' # or "es"
db_conn = initialize_conn(region)
db_conn.send_data()

并使用配置文件来存储您所在地区的端点,例如考虑YAML

# config.yml
es:
  db_name: es_sql_identity
fi:
  db_name: fi_sql_identity

然后在Python中使用它们:

import yaml

with open('config.yml') as f:
    config = yaml.safe_load(f)

region = 'fi'
db_name = config[region]['db_name'] # "fi_sql_identity"

# status = ...
result = phone_number(status, db_name)

有关使用YAML的其他信息,useful link

答案 1 :(得分:0)

首先,提供一种封装,方法是通过为该封装提供region参数来访问区域的资源。提供此功能作为behave fixture也是一个好主意。

案例1:区域参数需要随功能/场景而变化

例如,这意味着SCENARIO_1需要region =“ fi”,而SCENARIO_2需要region =“ es”。 使用具有区域参数的夹具和夹具标签。

在这种情况下,您需要为每个区域编写自己的方案(不良测试重用) 或使用ScenarioOutline作为模板让行为为您生成测试(例如,通过使用带有区域参数值的Fixture标签)。

案例2:区域参数对于所有功能/场景都是不变的(在测试运行期间)

您可以使用userdata参数来支持具有不同区域参数的多个测试运行。 看一下行为userdata的概念。 这使您可以运行behave -D region=fi ...behave -D region=es ...

这种情况可以更好地重用测试套件,这意味着测试套件的很大一部分是应用于所有区域的通用测试套件。

提示:您的代码示例过于具体(基于“ fi”),它是BAD-SMELL。