0

I'm writing test automation for API in BDD behave. I need a switcher between environments. Is any possible way to change one value in one place without adding this value to every functions? Example:

I've tried to do it by adding value to every function but its makes all project very complicated

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

what i what to switch only country value in headers e.g from 'fi' to 'es' and then all function should switch themselves to es environment, e.g

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

and when i will change from 'fi' to 'es' in headers i want:

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)

thx and please help

Bartol
  • 83
  • 1
  • 9
  • You know your code has syntax error right? – knh190 May 09 '19 at 05:02
  • You'd make the question a lot better if you showed (part of) the code that you're trying to improve and asking a question on how to go about that. Instead, you're sharing code that doesn't work with a question that doesn't make clear what problem you're really trying to solve. – Grismar May 09 '19 at 05:05
  • this is not my code. `value_1 from 'es'` means that i want to use `value_1` from 'es' environment, i'm not using code like this. Its just for better understanding the problem – Bartol May 09 '19 at 05:33
  • @Bartol The basic rule to get a helpful answer is to make your code minimal and runnable. But right now nobody knows what **precisely** you want to do, and your code is not syntax correct. – knh190 May 09 '19 at 05:38
  • @knh190 code is paste. I hope it is more clear now – Bartol May 09 '19 at 08:57
  • Don't know wether this solves your problem or not. But it's a common solution for most cases. – knh190 May 09 '19 at 09:14

2 Answers2

1

With respect to your original question, a solution for this case is 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)

Well, the problem is why do you hardcode everything? With the update you can simplify your function as:

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]

Also please don't write like:

# WRONG
fi_db_conn.send_data()

But use a parameter:

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

And use a config file to store your endpoints with respect to your region, e.g. consider YAML:

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

Then use them in 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)

See additional useful link for using YAML.

knh190
  • 2,744
  • 1
  • 16
  • 30
  • i have a api endpoints using data from db. To test it on different env, only what i have to do is change country in headers. But when i'm changing country i have to use specific for country SQL DB and couple dicts have to be change to other from another country. Thx for trying answer me, but this answer is not correct in my case. – Bartol May 09 '19 at 05:11
  • thanks for answer but I can't use yaml in pycharm community. I will have to find another way. – Bartol May 10 '19 at 05:26
  • @Bartol A Python dict is also fine.The idea is to not hardcode, but initialize connection using parameters. – knh190 May 10 '19 at 06:16
0

First, provide an encapsulation how to access the resources of a region by providing this encapsulation with a region parameter. It may also be a good idea to provide this functionality as a behave fixture.

CASE 1: region parameter needs to vary between features / scenarios

For example, this means that SCENARIO_1 needs region="fi" and SCENARIO_2 needs region="es". Use fixture and fixture-tag with region parameter.

In this case you need to write own scenarios for each region (BAD TEST REUSE) or use a ScenarioOutline as template to let behave generate the tests for you (by using a fixture-tag with a region parameter value for example).

CASE 2: region parameter is constant for all features / scenarios (during test-run)

You can support multiple test-runs with different region parameters by using a userdata parameter. Look at behave userdata concept. This allows you to run behave -D region=fi ... and behave -D region=es ...

This case provides a better reuse of testsuite, meaning a large part of the testsuite is the common testsuite that is applied to all regions.

HINT: Your code examples are too specific ("fi" based) which is a BAD-SMELL.

jenisys
  • 704
  • 5
  • 6