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.
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 == 2002. 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 == 2005. 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
pass7. 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
pass10. 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 == 200Each 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.
Test Development Learning Exchange
Test Development Learning Exchange
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.