2pytest fixtures for working with vcrpy to record HTTP requests.
4This allows us to record HTTP interactions as YAML files, so they can
5be "played back" later -- e.g. in automated tests or GitHub Actions.
6This means our tests are working with real responses, but don't
7depend on the original service being up and running.
9This establishes a couple of conventions for where cassettes are stored
12See https://vcrpy.readthedocs.io/
15from collections.abc import Iterator
19from vcr.cassette import Cassette
22__all__ = ["cassette_name", "vcr_cassette"]
25def get_cassette_name(request: pytest.FixtureRequest) -> str:
27 Return the name of a cassette for vcr.py.
29 The name can be made up of (up to) three parts:
31 - the name of the test class
32 - the name of the test function
33 - the ID of the test case in @pytest.mark.parametrize
36 name = request.node.name
38 # This is to catch cases where e.g. we try to include a complete
39 # HTTP URL in a cassette name, which creates very messy folders in
40 # the fixtures directory.
41 if any(char in name for char in ":/"):
43 "Illegal characters in VCR cassette name - "
44 "please set a test ID with pytest.param(…, id='…')"
47 if request.cls is not None:
48 return f"{request.cls.__name__}.{name}.yml"
54def cassette_name(request: pytest.FixtureRequest) -> str:
56 Return the filename of a VCR cassette to use in tests.
58 This is useful when you need some custom vcr.py options, and
59 can't use the prebuilt `vcr_cassette` fixture.
61 return get_cassette_name(request)
65def vcr_cassette(cassette_name: str) -> Iterator[Cassette]:
67 Create a VCR cassette for use in tests.
69 Tests will record their HTTP interactions as "cassettes" using vcr.py,
70 which can be replayed offline (e.g. in CI tests).
72 with vcr.use_cassette(
74 cassette_library_dir="tests/fixtures/cassettes",
75 decode_compressed_response=True,