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