Fundamentals 6 min read

Using pytest fixtures for API automation testing in Python

This article demonstrates how to leverage pytest fixtures to manage resources such as authentication tokens, database connections, temporary directories, API clients, environment variables, services, configuration files, caches, user roles, and HTTP headers, providing reusable and maintainable test code examples.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Using pytest fixtures for API automation testing in Python

1. Login authentication Token management

import pytest
import requests

@pytest.fixture(scope="module")
def login_token():
    # 登录获取Token的逻辑
    login_data = {"username": "testuser", "password": "testpass"}
    response = requests.post("https://api.example.com/auth/login", json=login_data)
    token = response.json()["token"]
    yield token
    # 清理逻辑,例如登出操作
    logout_url = "https://api.example.com/auth/logout"
    requests.post(logout_url, headers={"Authorization": f"Bearer {token}"})

def test_protected_endpoint(login_token):
    headers = {"Authorization": f"Bearer {login_token}"}
    response = requests.get("https://api.example.com/protected-endpoint", headers=headers)
    assert response.status_code == 200

2. Database connection and teardown

import sqlite3
import pytest

@pytest.fixture(scope="function")
def db_connection():
    conn = sqlite3.connect(":memory:")
    yield conn
    conn.close()

def test_db_insert(db_connection):
    cursor = db_connection.cursor()
    cursor.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)")
    cursor.execute("INSERT INTO test VALUES (1, 'example')")
    cursor.execute("SELECT * FROM test")
    rows = cursor.fetchall()
    assert rows == [(1, 'example')]

3. Temporary directory handling

import pytest
import os
import tempfile

@pytest.fixture(scope="function")
def temp_directory():
    with tempfile.TemporaryDirectory() as dir_path:
        yield dir_path

def test_write_and_read(temp_directory):
    with open(os.path.join(temp_directory, "test.txt"), "w") as file:
        file.write("Hello, World!")
    with open(os.path.join(temp_directory, "test.txt")) as file:
        content = file.read()
    assert content == "Hello, World!"

4. API client initialization and teardown

import requests
import pytest

@pytest.fixture(scope="session")
def api_client():
    client = requests.Session()
    yield client
    client.close()

def test_api_get(api_client):
    response = api_client.get("https://api.example.com/data")
    assert response.status_code == 200

5. Environment variable setup and restoration

import os
import pytest

@pytest.fixture(scope="function")
def set_env_variable():
    original_value = os.environ.get("SPECIAL_VAR", None)
    os.environ["SPECIAL_VAR"] = "test_value"
    yield
    if original_value is None:
        del os.environ["SPECIAL_VAR"]
    else:
        os.environ["SPECIAL_VAR"] = original_value

def test_env_var(set_env_variable):
    assert os.environ["SPECIAL_VAR"] == "test_value"

6. Service start and stop

import subprocess
import pytest

@pytest.fixture(scope="session")
def start_service():
    process = subprocess.Popen(["your-service-start-command"])
    yield
    process.terminate()
    process.wait(timeout=5)

def test_service_working(start_service):
    # Here you would add assertions to verify the service is running correctly
    pass

7. Configuration file loading and cleanup

import yaml
import pytest

@pytest.fixture(scope="function")
def load_config():
    with open("config.yaml", "r") as file:
        config = yaml.safe_load(file)
    yield config
    # If configuration changes need to be rolled back, handle it here

def test_config(load_config):
    assert load_config["database"]["host"] == "localhost"

8. Cache management

import cachetools
import pytest

@pytest.fixture(scope="session")
def cache():
    cache = cachetools.LRUCache(maxsize=100)
    yield cache
    cache.clear()

def test_cache(cache):
    cache["key"] = "value"
    assert cache["key"] == "value"

9. User role simulation

@pytest.fixture(params=["admin", "user", "guest"])
def user_role(request):
    return request.param

def test_access_rights(user_role):
    # Simulate permission checks based on role
    pass

10. HTTP header management

import pytest
import requests

@pytest.fixture
def custom_headers():
    headers = {"X-Custom-Header": "Value"}
    return headers

def test_with_custom_headers(custom_headers):
    response = requests.get("https://api.example.com", headers=custom_headers)
    assert response.status_code == 200

Each example shows how to define a pytest fixture to initialize a resource and then use that fixture in test functions; adjust URLs, database strings, and other configurations as needed for your specific environment and ensure required libraries (requests, pytest, cachetools, etc.) are installed.

pythonAutomationpytestapi-testingfixtures
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.