Scrum Masters

Passing Test Inputs into pytest


S omebody just recently asked me this concern:

I’m establishing a pytest task to check an API. How can I pass environment details into my tests? I require to run tests versus various environments like DEV, TEST, and PROD. Each environment has a various URL and a special set of users.

This is a typical issue for automatic test suites, not simply in Python or pytest. Any details a test requires about the environment under test is called setup metadata URLs and user accounts prevail setup metadata worths. Tests require to understand what website to strike and how to confirm.

Utilizing config files with an environment variable

There are lots of methods to manage inputs like this. I like to develop JSON files to save the setup metadata for each environment. So, something like this:

  • dev.json
  • test.json
  • prod.json

Every one might appear like this:

{
" base_url": ".
" username": "pandy",.
" password": "DandyAndySugarCandy".
}

The structure of each file need to be the exact same so that tests can treat them interchangeably.

I like utilizing JSON files due to the fact that:

  • they appear text files with a basic format
  • they are simple to diff
  • they save information hierarchically
  • Python’s requirement json module turns them into dictionaries in 2 lines flat

Then, I develop an environment variable to set the preferred config file:

export TARGET_ENV= dev.json.

In my pytest task, I compose a component to get the config file course from this environment variable and after that checked out that file as a dictionary:

import json.
import os.
import pytest.

@pytest. component.
def target_env( scope=" session"):
config_path = os.environ['TARGET_ENV']
with open( config_path) as config_file:.
config_data = json.load( config_file).
return config_data.

I’ll put this component in a conftest.py file so all tests can share it. Considering that it utilizes session scope, pytest will perform it one time prior to all tests. Test functions can call it like this:

import demands.

def test_api_get( target_env):.
url = target_env['base_url']
creds = (target_env['username'], target_env['password']).
action = requests.get( url, auth= creds).
assert response.status _ code == 200.

Picking the config file with a command line argument

If you do not wish to utilize environment variables to pick the config file, you might rather develop a custom-made pytest command line argument. Bas Dijkstra composed an outstanding post demonstrating how to do this. Generally, you might include the list below function to conftest.py to include the custom-made argument:

def pytest_addoption( parser):.
parser.addoption(.
'-- target-env',.
action=' shop',
default=" dev.json",
assistance=' Course to the target environment config file').

Then, upgrade the target_env component:

import json.
import pytest.

@pytest. component.
def target_env():.
config_path = request.config.getoption('-- target-env').
with open( config_path) as config_file:.
config_data = json.load( config_file).
return config_data.

When running your tests, you would define the config file course like this:

python -m pytest-- target-env dev.json.

Why trouble with JSON files?

In theory, you might pass all inputs into your tests with pytest command line arguments or environment variables. You do not requirement config files. Nevertheless, I discover that saving setup metadata in files is a lot more practical than setting a lot of inputs each time I require to run my tests. In our example above, passing one worth for the config file course is a lot easier than passing 3 various worths for base URL, username, and password. Real-world test tasks may require more inputs. Plus, setups do not alter frequency, so it’s alright to conserve them in a declare duplicated usage. Simply make certain to keep your config files safe if they have any tricks.

Confirming inputs

Whenever checking out inputs, it’s excellent practice to make certain their worths are excellent. Otherwise, tests might crash! I like to include a couple of standard assertions as security checks:

import json.
import os.
import pytest.

@pytest. component.
def target_env():.
config_path = request.config.getoption('-- target-env').
assert os.path.isfile( config_path).

with open( config_path) as config_file:.
config_data = json.load( config_file).

assert 'base_url' in config_data.
assert 'username' in config_data.
assert 'password' in config_data.

return config_data.

Now, pytest will stop right away if inputs are incorrect.


Source link