pytest-vcr

repository·master·Indexed 41 days ago

https://github.com/ktosiek/pytest-vcr

A pytest plugin for managing VCR.py cassettes. It records HTTP interactions during test execution and replays them in future runs to ensure tests are fast, deterministic, and independent of live external services. Features include the @pytest.mark.vcr marker for configuration, CLI options like --vcr-record and --disable-vcr, and fixtures for customizing cassette directories and filtering sensitive headers.

Tokens
1.5K
Snippets
11
Records
11
Agent score
51%

What's inside pytest-vcr

  1. Run pytest-vcr on CI

    master

    When running tests in a Continuous Integration (CI) environment, use the --vcr-record=none option. This ensures that tests only use existing cassettes and fail if a cassette is missing, preventing the CI from attempting to record new interactions and verifying that all necessary cassettes have been committed to the repository.

    pytest --vcr-record=none
  2. Generate combined test coverage reports

    master

    When running tests via tox, coverage data is collected in parallel mode across different environments. To merge these results and generate a human-readable HTML report, run the following commands:

    coverage combine && coverage html
  3. Configure pytest-vcr using fixtures

    master

    You can customize the VCR behavior by overriding specific pytest fixtures at the module scope:

    • vcr_config: A dictionary containing additional arguments for the VCR constructor. Note that values here are overridden by marker options and command-line arguments.
    • vcr_cassette_dir: The path to the directory where cassettes are stored. Defaults to test_file_directory + "/cassettes/".
    • vcr_cassette_name: The name of the cassette for the current test. Defaults to the name of the test.
    • vcr: The VCR instance used for creating cassettes. Override this to register custom matchers, serializers, or persisters.
    @pytest.fixture(scope='module')
    def vcr(vcr):
        vcr.register_matcher('my_matcher', my_matcher)
        vcr.match_on = ['my_matcher']  # This can also go into vcr_config or marker kwargs
        return vcr
  4. Filter sensitive headers in cassettes

    master

    To prevent secrets like API keys or passwords from being saved in your cassettes, use the vcr_config fixture to define filter_headers. This allows you to replace specific request/response headers with a placeholder value (e.g., DUMMY).

    @pytest.fixture(scope='module')
    def vcr_config():
        return {
            # Replace the Authorization request header with "DUMMY" in cassettes
            "filter_headers": [('authorization', 'DUMMY')],
        }
  5. Use @pytest.mark.vcr to record and replay HTTP interactions

    master

    To record HTTP interactions into a cassette, annotate your test function with the @pytest.mark.vcr() decorator.

    On the first run, the plugin will execute the test and record the network interactions into a new YAML file located in a cassettes/ directory adjacent to your test file (e.g., cassettes/test_iana.yaml). On subsequent runs, the plugin will replay the recorded interactions from the cassette instead of making real network requests.

    Note: You should commit the generated cassette files to your version control system (VCS).

    @pytest.mark.vcr()
    def test_iana():
        response = urlopen('http://www.iana.org/domains/reserved').read()
        assert b'Example domains' in response
  6. Change the cassettes library path

    master

    By default, pytest-vcr stores cassettes in a cassettes directory adjacent to the test file. You can override this behavior by providing a custom vcr_cassette_dir fixture. This is useful for organizing cassettes into a specific directory structure, such as vhs/{module}/{test}.yaml.

    @pytest.fixture(scope='module')
    def vcr_cassette_dir(request):
        # Put all cassettes in vhs/{module}/{test}.yaml
        return os.path.join('vhs', request.module.__name__)
  7. Use the @pytest.mark.vcr marker

    master

    The @pytest.mark.vcr marker allows you to pass configuration options directly to the VCR constructor for specific tests. Any keyword argument passed to the marker is treated as a VCR constructor argument.

    Example usage:

    @pytest.mark.vcr(ignore_localhost=True)
    def test_local_and_remote():
        # This one will replay from the cassette
        urlopen('http://www.iana.org/domains/reserved').read()
        # This one will always be downloaded (because it is localhost)
        urlopen('http://127.0.0.1/').read()
    @pytest.mark.vcr(ignore_localhost=True)
    def test_local_and_remote():
        urlopen('http://www.iana.org/domains/reserved').read()
        urlopen('http://127.0.0.1/').read()
  8. Configure pytest-vcr via command line options

    master

    You can control VCR recording behavior directly from the CLI using the following flags:

    • --vcr-record: Selects the VCR.py record mode. For example, use --vcr-record=none in CI environments to ensure tests only replay existing cassettes and do not attempt to make new network requests.
    • --disable-vcr: Disables both replaying and recording. The VCR plugin remains installed but will not intercept or affect any network requests.
    pytest --vcr-record=none
    pytest --disable-vcr