Pytest Parametrization: Injecting Data into Tests
Pytest framework, one of the best frameworks in Python ecosystem

Pytest Parametrization: Injecting Data into Tests

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:

  1. test_post_user: This test is parameterized with the user_payloads data from the YAML file. It makes HTTP POST requests to the /users endpoint with the specified payloads and verifies the response status code and data.
  2. test_insert_user: This test is parameterized with the users data from the YAML file. It connects to a database and inserts the user data into a table.
  3. test_write_file: This test is parameterized with the file_contents data from the YAML file. It creates temporary files and writes the specified content to them.

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.



#python #pytest #automation #tests

要查看或添加评论,请登录

Mor Dabastany???的更多文章

社区洞察

其他会员也浏览了