| name | pytest-vcr |
|---|---|
| description | Record, rewrite, and debug VCR cassettes for HTTP recordings. Use when running tests with --record-mode, verifying cassette playback, or inspecting request/response bodies in YAML cassettes. |
| allowed-tools | Bash(uv run pytest *), Bash(uv run python .agents/skills/pytest-vcr/parse_cassette.py *), Bash(.agents/skills/pytest-vcr/run-vertex-tests.sh *), Bash(source .env && uv run pytest *), Bash(git diff *) |
Use this skill when recording or re-recording VCR cassettes for tests, or when debugging cassette contents.
- Verify
.envexists:test -f .env && echo 'ok' || echo 'missing' - Missing API keys will cause clear test errors at runtime
--record-mode=rewrite: Record cassettes (works for both new and existing)--lf: Run only the last failed tests-vv: Verbose output--tb=line: Short traceback output-k="": Run tests matching the given substring expression
source .env && uv run pytest path/to/test.py::test_function_name -v --tb=line --record-mode=rewriteMultiple tests can be specified:
source .env && uv run pytest path/to/test.py::test_one path/to/test.py::test_two -v --tb=line --record-mode=rewriteRun the same tests WITHOUT --record-mode to verify cassettes play back correctly:
source .env && uv run pytest path/to/test.py::test_function_name -vv --tb=lineIf tests use snapshot() assertions:
- The test run in Step 2 auto-fills snapshot content
- Review the generated snapshot files to ensure they match expected output
- You only review - don't manually write snapshot contents
- Snapshots capture what the test actually produced, additional to explicit assertions
Parse VCR cassette YAML files to inspect request/response bodies without dealing with raw YAML.
uv run python .agents/skills/pytest-vcr/parse_cassette.py <cassette_path> [--interaction N]# Parse all interactions in a cassette
uv run python .agents/skills/pytest-vcr/parse_cassette.py tests/models/cassettes/test_foo/test_bar.yaml
# Parse only interaction 1 (0-indexed)
uv run python .agents/skills/pytest-vcr/parse_cassette.py tests/models/cassettes/test_foo/test_bar.yaml --interaction 1For each interaction, shows:
- Request: method, URI, parsed body (truncated base64)
- Response: status code, parsed body (truncated base64)
Base64 strings longer than 100 chars are truncated for readability.
Vertex tests use the skip_unless_vertex fixture from tests/conftest.py — they only run in CI or when ENABLE_VERTEX=1 is set. ENABLE_VERTEX=1 is only needed when recording/rewriting cassettes locally; during playback, cassettes replay without live auth. Add skip_unless_vertex: None as a parameter to any new vertex test.
Vertex auth works two ways:
GOOGLE_APPLICATION_CREDENTIALS: set this env var to a service account JSON path — no gcloud needed- gcloud: the script auto-detects project and checks auth via
gcloud
Use the provided script:
# Record Vertex cassettes
.agents/skills/pytest-vcr/run-vertex-tests.sh tests/path/to/test.py -v --tb=line --record-mode=rewrite
# Verify playback
.agents/skills/pytest-vcr/run-vertex-tests.sh tests/path/to/test.py -vv --tb=lineIf using gcloud and auth fails:
gcloud auth application-default login
gcloud config set project <your-project-id># 1. Record cassette
source .env && uv run pytest tests/models/test_openai.py::test_chat_completion -v --tb=line --record-mode=rewrite
# 2. Verify playback and fill snapshots
source .env && uv run pytest tests/models/test_openai.py::test_chat_completion -vv --tb=line
# 3. Review test code diffs (excludes cassettes)
git diff tests/ -- ':!**/cassettes/**'
# 4. List new/changed cassettes (name only - use parse_cassette.py to inspect)
git diff --name-only tests/ -- '**/cassettes/**'
# 5. Inspect cassette contents if needed
uv run python .agents/skills/pytest-vcr/parse_cassette.py tests/models/cassettes/test_openai/test_chat_completion.yaml