Pytest Parametrization: Injecting Data into Tests
Mor Dabastany???
Automation and Infrastructure lead || Python and Playwright advocate
As already mentioned in previous article, Pytest is a powerful testing framework for Python that offers a wide range of features, including parametrization. Parametrization allows you to run the same test with different sets of input data, making it easier to test multiple scenarios without duplicating code.
Parameterizing Tests
Pytest provides the @pytest.mark.parametrize decorator to parameterize tests. This decorator takes two arguments: the name of the parameter(s) and a list of input data. Here's a simple example:
import pytest
@pytest.mark.parametrize("num1, num2, expected", [
(2, 3, 5),
(4, 5, 9),
(6, 7, 13)
])
def test_add(num1, num2, expected):
assert num1 + num2 == expected
In this example, the test_add function is parameterized with three arguments: num1, num2, and expected. The @pytest.mark.parametrize decorator specifies the input data as a list of tuples, where each tuple represents a set of test inputs.
Parameterizing Tests Via Test Data File
Another option for generating inputs for tests is using a file that will act as a config inputs or manifest file. In this example, we'll be using YAML based file.
领英推荐
import pytest
import yaml
# Load test data from YAML file
with open("test_data.yaml", "r") as file:
test_data = yaml.safe_load(file)
# Parametrized test for making HTTP requests
@pytest.mark.parametrize("payload", test_data["user_payloads"])
def test_post_user(payload):
import requests
url = "https://api.example.com/users"
response = requests.post(url, json=payload)
assert response.status_code == 201
assert response.json()["name"] == payload["name"]
assert response.json()["age"] == payload["age"]
# Parametrized test for database operations
@pytest.mark.parametrize("user", test_data["users"])
def test_insert_user(user):
import database
db = database.connect()
cursor = db.cursor()
query = "INSERT INTO users (name, age) VALUES (%s, %s)"
cursor.execute(query, (user["name"], user["age"]))
db.commit()
cursor.close()
db.close()
# Add assertions to verify the insertion
# Parametrized test for file operations
@pytest.mark.parametrize("file_data", test_data["file_contents"])
def test_write_file(file_data, tmp_path):
file_path = tmp_path / "test_file.txt"
with open(file_path, "w") as file:
file.write(file_data["content"])
# Add assertions to verify the file content
In this example, we first load the test data from a YAML file named test_data.yaml. The YAML file could look something like this:
user_payloads:
- name: Alice
age: 25
- name: Bob
age: 30
- name: Charlie
age: 35
users:
- name: David
age: 40
- name: Eve
age: 45
file_contents:
- content: "This is a test file."
- content: "Another test file content."
We then define three parametrized tests:
By using parametrization and reading test data from a YAML file, one can easily manage and maintain test cases for different scenarios. The YAML file provides a centralized location for storing test data, making it easier to modify or add new test cases without modifying the test code itself.