pytest-recording
pytest-recording is a pytest plugin that integrates VCR.py to record and replay HTTP traffic during tests. It aims to make testing code that interacts with external services faster and more reliable by preventing unnecessary network requests. The library uses VCR.py's 'none' recording mode by default to avoid unintentional live network calls. The current version is 0.13.4, and it maintains an active release cadence.
Warnings
- breaking `pytest-recording` is incompatible with `pytest-vcr`. If you have `pytest-vcr` installed, you must uninstall it before using `pytest-recording` to avoid conflicts.
- gotcha By default, `pytest-recording` uses VCR.py's `none` recording mode, which blocks all network requests and will cause tests to fail if a cassette doesn't exist. To allow network requests for initial recording or updates, you must explicitly set a recording mode (e.g., `once`, `all`, `new_episodes`) via the `--record-mode` CLI option.
- gotcha Sensitive information like API keys, authorization tokens, or personally identifiable information can easily be recorded into VCR.py cassettes. This poses a security risk if cassettes are committed to version control.
- gotcha Configuration parameters for VCR.py can be provided via the `vcr_config` fixture (at session, package, module, or function scope) and via individual `pytest.mark.vcr` decorators. These configurations are merged, with more narrowly scoped settings (e.g., function-level mark) taking precedence over broader ones (e.g., session-level fixture).
Install
-
pip install pytest-recording
Imports
- pytest.mark.vcr
import pytest # Use as decorator: @pytest.mark.vcr
- vcr_config fixture
import pytest @pytest.fixture(scope='module') def vcr_config(): return {'filter_headers': ['Authorization']}
Quickstart
import pytest
import requests
import os
# Define a vcr_config fixture in conftest.py or test file scope
@pytest.fixture(scope="module")
def vcr_config():
"""
Global VCR.py configuration for all tests in this module/session.
Filters out sensitive Authorization headers to prevent them from being written to cassettes.
"""
return {"filter_headers": ["Authorization"], "ignore_localhost": True}
@pytest.mark.vcr
def test_http_get_request():
"""
Records a simple HTTP GET request to httpbin.org.
The cassette will be saved in a default location, e.g., cassettes/{module_name}/test_http_get_request.yaml.
"""
response = requests.get("http://httpbin.org/get")
assert response.status_code == 200
assert response.json()["url"] == "http://httpbin.org/get"
@pytest.mark.vcr
def test_authenticated_api_call():
"""
Demonstrates recording an API call with an Authorization header.
The header is filtered by the vcr_config fixture defined above.
"""
# Simulate retrieving an API key from environment variables
api_key = os.environ.get('PYTEST_TEST_API_KEY', 'fake_api_key_123')
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get("http://httpbin.org/headers", headers=headers)
assert response.status_code == 200
# Verify that the Authorization header is not in the recorded response (due to filtering)
assert "Authorization" not in response.json().get("headers", {})
assert "fake_api_key_123" not in str(response.json()) # Ensure actual key content not present