VCR.py graba respuestas HTTP en cassettes y las reproduce después. Las pruebas de integración se vuelven rápidas, pero el archivo puede contener headers, tokens y datos personales.
import requests
import vcr
grabador = vcr.VCR(
record_mode="once",
filter_headers=["authorization"],
filter_query_parameters=["api_key"],
)
@grabador.use_cassette("tests/cassettes/status.yaml")
def test_status() -> None:
response = requests.get("https://api.example.com/status", timeout=5)
assert response.status_code == 200
once graba si falta el cassette y luego exige coincidencia. Revisa el YAML antes del commit y filtra cookies, cuerpos e identificadores. No grabes producción sin autorización.
Usa mocks en pruebas unitarias y VCR.py en integraciones. Para HTTPX consulta RESPX; para requests revisa requests en Python.
La documentación oficial de VCR.py, consultada el 22 de julio de 2026, cubre matchers, filtros y modos. Define una política de actualización y conserva pruebas de contrato reales controladas.
Elige el record mode a propósito
once es el valor habitual para CI: crea el cassette en local, haz commit y falla si aparece una interacción nueva. none nunca graba y solo reproduce, más seguro cuando quieres garantizar ejecución offline. new_episodes añade interacciones no vistas y puede ocultar drift si el diff no se revisa con cuidado. all reescribe siempre y encaja mal en suites compartidas.
Graba contra una API de staging o sandbox con credenciales sintéticas. No apuntes una sesión de grabación a datos de clientes en producción. Cuando cambie el contrato remoto, borra o regenera el cassette afectado a propósito, en lugar de editar YAML a mano, salvo un ajuste trivial de filtro.
Filtra secretos antes de que exista el cassette
Los filtros se ejecutan antes de persistir. Configura filter_headers, filter_query_parameters y filter_post_data_parameters para tokens, claves de API, cookies de sesión y contraseñas. Para cuerpos que incrustan secretos en JSON, usa un callback before_record que redacte campos por nombre.
def limpiar_cuerpo(request):
if request.body and b"password" in request.body:
request.body = b'{"password":"<FILTERED>"}'
return request
grabador = vcr.VCR(
record_mode="once",
filter_headers=["authorization", "cookie"],
before_record_request=limpiar_cuerpo,
)
Revisa el cassette en el pull request con el mismo cuidado que el código de la aplicación. Un bearer token filtrado en YAML sigue siendo un secreto. Prefiere valores placeholder que mantengan la estructura legible para depurar.
Haz match de lo que importa en la solicitud
Por defecto VCR.py combina método y URI. Añade matchers cuando el mismo endpoint se llama con cuerpos o headers distintos que cambian la respuesta, como body, headers o matchers personalizados. Emparejar de más vuelve el cassette frágil; emparejar de menos puede reproducir la interacción equivocada.
Normaliza partes volátiles de la URI cuando aparecen timestamps o IDs aleatorios en la ruta. O estabiliza el cliente bajo prueba, o enseña al matcher a ignorar esos segmentos. Afirma resultados de dominio en la prueba, no cada header grabado en el cassette.
Organiza cassettes como fixtures
Mantén un cassette por escenario con una ruta descriptiva, por ejemplo tests/cassettes/pagos/crear_exito.yaml. Compartir un cassette grande entre pruebas no relacionadas hace dolorosa la renovación y ruidosa la revisión. Nombra los archivos por el comportamiento bajo prueba, no por la biblioteca del cliente HTTP.
Versiona cassettes con la suite cuando CI deba ejecutarse sin red. Documenta quién los regenera y con qué frecuencia. Una renovación trimestral, más una bajo demanda tras cambios conocidos de la API, suele bastar. Empareja las pruebas con cassette a una suite pequeña de contrato en vivo, programada o detrás de un marker explícito.
Cuándo VCR.py es la herramienta equivocada
Las pruebas unitarias que solo necesitan un JSON fijo suelen quedar más claras con un mock de transport o una interfaz de cliente stub. VCR.py brilla cuando la construcción de URL, headers, redirects y formas reales de respuesta importan juntos. Es más débil cuando cada ejecución debe mutar estado remoto que no se puede reproducir con seguridad.
El código HTTPX async puede exigir un adapter u otra biblioteca de mock. Confirma el soporte antes de adoptar VCR.py como única estrategia de integración. Mantén timeouts en el cliente bajo prueba para que una grabación en vivo mal configurada falle rápido en lugar de colgar la suite.
Lista operativa
Antes del merge, confirma que los filtros eliminan secretos, que el record mode no puede alcanzar la red por accidente en CI, que se revisó el diff de los cassettes y que existe un plan de renovación. Ejecuta la suite offline al menos una vez. Mantén una verificación en vivo rara y separada para el contrato remoto.
VCR.py convierte una conversación HTTP real en una fixture reproducible. Trátala como configuración sensible: filtrada, versionada, renovada a propósito y nunca confundida con un sustituto completo de las pruebas de contrato.