I have some test cases and test data where test data is in JSON array form as below:
{
"valid_data": [
{
"id": "1234",
"name": "John"
},
{
"id": "2234",
"name": "Mary"
},
{
"id": "3234",
"name": "Kenny"
},
],
"invalid_data": [
{
"id": "1234",
"name": "Mary"
},
{
"id": "2234",
"name": "Kenny"
},
{
"id": "3234",
"name": "John"
},
]
}
I am now testing an API which will take in JSON as input and will respond with a status code. If the id and name match inside the database, it will respond with 200 OK. Else with 400 Bad Request.
So here are my current test cases:
def get_test_data(filename):
folder_path = os.path.abspath(Path(os.path.dirname(__file__)))
folder = os.path.join(folder_path, 'TestData')
jsonfile = os.path.join(folder, filename)
with open(jsonfile) as file:
data = json.load(file)
return data
def test_valid_ok(database_api):
data = get_test_data('test_data.json')
response = database_api.get_user_info(data)
assert requests.codes['ok'] == response.status_code
In my conftest I just declared the method database_api
and take in the URL as the parameter then it will send a post request to the api. For this part had no problem I have tested which is working fine.
However with current structure and code, I can only have 1 json data inside the json file. I would like to have a data-driven test which able to run multiple times based on my test data inside the json file.
I have checked the pytest official documents and various online sources which suggest to use pytest parametrized function but I couldn't get it right with json file.
Thanks if anyone could help!
Parametrized tests The above decorator is a very powerful functionality, it permits to call a test function multiple times, changing the parameters input at each iteration.
To access the fixture function, the tests have to mention the fixture name as input parameter. Pytest while the test is getting executed, will see the fixture name as input parameter. It then executes the fixture function and the returned value is stored to the input parameter, which can be used by the test.
PyTest is a testing framework that allows users to write test codes using Python programming language. It helps you to write simple and scalable test cases for databases, APIs, or UI. PyTest is mainly used for writing tests for APIs. It helps to write tests from simple unit tests to complex functional tests.
You can use pytest_generate_tests hook for parametrizing with dynamic data.
First create a fixture that can be called by the test function to get the test data.
# in conftest.py
@pytest.fixture()
def test_data(request):
return request.param
Now you can parametrize it so that it is called for each test data set:
#in conftest.py
def pytest_generate_tests(metafunc):
testdata = get_test_data('test_data.json')
metafunc.parametrize('test_data', testdata, indirect=True)
The testdata
passed to the parametrize
function has to be a list. So you need to modify the input data a bit before passing it. I modified the get_test_data
function a bit.
#in conftest.py
def get_test_data(filename):
folder_path = os.path.abspath(os.path.dirname(__file__))
folder = os.path.join(folder_path, 'TestData')
jsonfile = os.path.join(folder, filename)
with open(jsonfile) as file:
data = json.load(file)
valid_data = [(item, 1) for item in data['valid_data']]
invalid_data = [(item, 0) for item in data['invalid_data']]
# data below is a list of tuples, with first element in the tuple being the
# arguments for the API call and second element specifies if this is a test
# from valid_data set or invalid_data. This can be used for putting in the
# appropriate assert statements for the API response.
data = valid_data + invalid_data
return data
And now your test function could look like:
#in test_API.py
def test_(test_data):
response = database_api.get_user_info(test_data[0])
# Add appropriate asserts.
# test_data[1] == 1 means 200 response should have been received
# test_data[1] == 0 means 400 response should have been received
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With