Master Data‑Driven API Testing with Pytest’s @parametrize
This guide explains why data‑driven testing is essential for API automation, introduces Pytest’s powerful @pytest.mark.parametrize decorator, and provides step‑by‑step examples—including single‑parameter, multi‑parameter, dynamic data generation, fixture integration, and external data sources—to boost test coverage and maintainability.
Why Data‑Driven Testing Matters
Separating test logic from test data reduces code duplication, improves coverage by exercising many input combinations, and makes tests more flexible because data can be added or changed without touching the test code.
Pytest’s @pytest.mark.parametrize Decorator
The decorator lets you supply multiple sets of input data to a test function, supporting single‑parameter tests, multi‑parameter combination tests, and dynamic data generation from functions.
1. Single‑Parameter Test Example
import pytest
@pytest.mark.parametrize("a, b, expected", [
(1, 1, 2),
(2, 3, 5),
(5, 5, 10),
(0, 0, 0),
(-1, 1, 0)
])
def test_addition(a, b, expected):
assert a + b == expectedPytest runs test_addition once for each tuple.
2. Multi‑Parameter Combination Test Example
import pytest
@pytest.mark.parametrize("username, password, expected_status", [
("user1", "pass1", 200),
("user2", "wrong_pass", 401),
("admin", "admin123", 200),
("guest", "guest", 200),
("", "", 400),
("user1", "", 400),
("", "pass1", 400)
])
def test_login(username, password, expected_status):
url = "https://api.example.com/login"
data = {"username": username, "password": password}
response = requests.post(url, json=data)
assert response.status_code == expected_statusThis checks various credential combinations against the login endpoint.
3. Dynamic Data Generation
import pytest
def generate_test_data():
return [
(1, 1, 2),
(2, 3, 5),
(5, 5, 10),
(0, 0, 0),
(-1, 1, 0)
]
@pytest.mark.parametrize("a, b, expected", generate_test_data())
def test_addition(a, b, expected):
assert a + b == expectedThe function supplies data at runtime, keeping the test suite adaptable.
Combining Fixtures with parametrize
import pytest
@pytest.fixture
def base_url():
return "https://api.example.com"
@pytest.mark.parametrize("endpoint, status_code", [
("/users", 200),
("/posts", 200),
("/comments", 200),
("/invalid", 404)
])
def test_api_endpoints(base_url, endpoint, status_code):
url = base_url + endpoint
response = requests.get(url)
assert response.status_code == status_codeThe fixture provides the common base URL while the decorator supplies different endpoints and expected codes.
Using External Data Sources
import pytest, json
def load_test_data():
with open("test_data.json", "r") as f:
return json.load(f)
@pytest.mark.parametrize("data", load_test_data())
def test_api(data):
url = data["url"]
expected_status = data["expected_status"]
response = requests.get(url)
assert response.status_code == expected_statusTest data stored in a JSON file is loaded at runtime, allowing non‑technical team members to edit test cases without touching code.
Conclusion
Pytest’s @pytest.mark.parametrize makes data‑driven API testing straightforward, boosting efficiency and coverage. By pairing it with fixtures and external data sources, you gain even greater flexibility and maintainability in your automated test suite.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
