kiwicom / pytest-recording

A pytest plugin that allows recording network interactions via VCR.py
MIT License
425 stars 34 forks source link

[BUG] cassette_library_dir from vcr_config is ignored when searching for extra cassettes #151

Open LucHermitte opened 1 week ago

LucHermitte commented 1 week ago

Describe the bug

When a test depends on extra shared cassettes, we cannot override the default vcr_cassette_dir through cassette_library_dir key returned from vcr_config fixture.

While vcr_cassette_dir is correctly used to set where the current cassette is read/written, it's ignored when searching for extra cassettes.

To Reproduce A simplified Minimal (Not Working) Example would be:

# file: test_eof.py

@pytest.fixture(scope="module")
def vcr_config(baseline_dir):
    # baseline_dir being another fixture set elsewhere
    assert os.path.exists(baseline_dir)
    return {
            "cassette_library_dir"       : os.path.join(baseline_dir, 'cassettes/test_eof'),
            # I guess I should be able to use module.purebasename instead of hardcoding "test_eof"
    }

@pytest.mark.vcr("cop_access_token.yaml")
def test_sometest():
    Code that executes a request that I expect recorded in:
   -> ${BASELINE_DIR}/cassettes/test_eof/cop_access_token.yaml
    But the cassettes searched are:
    - $(current_test_dir)/cassettes/test_eof/cop_access_token.yaml  <-- not the path expected
    - and ${BASELINE_DIR}/cassettes/test_eof/test_sometest.yaml <- the current test

Expected behavior The shared cassettes should be searched in vcr_config()["cassette_library_dir"]

Possible patch Adding the following instruction in _vcr.use_cassette() seems enough to fix the issue.

    # just after >> merged_config = merge_kwargs(config, markers) <<
    vcr_cassette_dir = config.get('cassette_library_dir', vcr_cassette_dir)  # <<-- The proposed fix

Or maybe, it's vcr_cassette_dir fixture itself that needs the patching? I don't know what's better.

@pytest.fixture(scope="module")  # type: ignore
def vcr_cassette_dir(request: SubRequest) -> str:
    """Each test module has its own cassettes directory to avoid name collisions.

    For example each test module could have test function with the same names:
      - test_users.py:test_create
      - test_profiles.py:test_create
    """
+    config = request.getfixturevalue("vcr_config")
+    if "cassette_library_dir" in config:
+        return config["cassette_library_dir"]
    module = request.node.fspath  # current test file
    return os.path.join(module.dirname, "cassettes", module.purebasename)

Environment:

LucHermitte commented 1 week ago

My mistake, it seems we can simply override vcr_cassette_dir. It deserved to be documented though.

It's not much a bug then, but more an opportunity to improve documentation.