Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] "Lazy load" VCR to reduce plugin overhead #145

Closed
herbierand opened this issue Jul 8, 2024 · 2 comments
Closed

[FEATURE] "Lazy load" VCR to reduce plugin overhead #145

herbierand opened this issue Jul 8, 2024 · 2 comments

Comments

@herbierand
Copy link
Contributor

Is your feature request related to a problem? Please describe.

The plugin currently imports vcr regardless of whether any vcr-marked tests are collected by pytest. This import can be slow (on the order of hundreds of milliseconds) in environments where multiple HTTP client libraries supported by VCR.py are installed.

Describe the solution you'd like

Implement "lazy importing" of vcr so that the cost of importing it is incurred only when necessary. For example, move the from ._vcr import use_cassette import inside the vcr fixture in plugin.py:

@pytest.fixture(autouse=True)  # type: ignore
def vcr(
    request: SubRequest,
    vcr_markers: List[Mark],
    vcr_cassette_dir: str,
    record_mode: str,
    disable_recording: bool,
    pytestconfig: Config,
) -> Iterator[Optional["Cassette"]]:
    """Install a cassette if a test is marked with `pytest.mark.vcr`."""
    if disable_recording:
        yield None
    elif vcr_markers:

        # IMPORT HERE
        from ._vcr import use_cassette

        config = request.getfixturevalue("vcr_config")
        default_cassette = request.getfixturevalue("default_cassette_name")
        with use_cassette(
            default_cassette,
            vcr_cassette_dir,
            record_mode,
            vcr_markers,
            config,
            pytestconfig,
        ) as cassette:
            yield cassette
    else:
        yield None

Describe alternatives you've considered

I considered disabling the plugin by default and re-enabling it after a vcr-marked test is collected. However, this approach is not feasible because the plugin relies on hooks that must execute before test collection.

Additional context

I measured the overhead of importing vcr in an environment with all the VCR.py compatible http client libraries installed (https://vcrpy.readthedocs.io/en/latest/installation.html#compatibility).

In a Python REPL (Macbook Pro M2):

>>> import time
>>> start = time.time(); import vcr; elapsed = time.time() - start
>>> elapsed
0.2606179714202881

Without this cost, the plugin could be enabled by default with minimal overhead.

If deemed appropriate, I would be willing to contribute a PR.

@Stranger6667
Copy link
Collaborator

Thanks! Sounds good to me!

@Stranger6667
Copy link
Collaborator

Solved in #146

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants