Skip to content

Commit

Permalink
chore: Lazily evaluate the vcr_config fixture
Browse files Browse the repository at this point in the history
  • Loading branch information
Stranger6667 committed Jun 20, 2022
1 parent 906e597 commit dafd141
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 18 deletions.
44 changes: 26 additions & 18 deletions src/pytest_recording/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ def pytest_configure(config: Config) -> None:
)
config.addinivalue_line("markers", "vcr: Mark the test as using VCR.py.")
config.addinivalue_line("markers", "block_network: Block network access except for VCR recording.")
config.addinivalue_line("markers", "default_cassette: Override the default cassette name..")
config.addinivalue_line("markers", "default_cassette: Override the default cassette name.")
config.addinivalue_line(
"markers", "allowed_hosts: List of regexes to match hosts to where connection must be allowed"
"markers", "allowed_hosts: List of regexes to match hosts to where connection must be allowed."
)
network.install_pycurl_wrapper()

Expand Down Expand Up @@ -83,41 +83,49 @@ def vcr_config() -> Dict:


@pytest.fixture # type: ignore
def vcr_markers(request: SubRequest) -> List[Mark]:
"""All markers applied to the certain test together with cassette names associated with each marker."""
return list(request.node.iter_markers(name="vcr"))


@pytest.fixture(autouse=True) # type: ignore
def block_network(request: SubRequest, record_mode: str, vcr_markers: List[Mark]) -> Iterator[None]:
"""Block network access in tests except for "none" VCR recording mode."""
marker = request.node.get_closest_marker(name="block_network")
if marker is not None:
validate_block_network_mark(marker)
def allowed_hosts(request: SubRequest) -> List[str]:
"""List of regexes to match hosts to where connection must be allowed."""
block_network = request.node.get_closest_marker(name="block_network")
config = request.getfixturevalue("vcr_config")
# If network blocking is enabled there is one exception - if VCR is in recording mode (any mode except "none")
# Take `--allowed-hosts` with the most priority:
# - `block_network` mark
# - CLI option
# - vcr_config fixture
default_block = marker or request.config.getoption("--block-network")
# - `vcr_config` fixture
allowed_hosts = (
getattr(marker, "kwargs", {}).get("allowed_hosts")
getattr(block_network, "kwargs", {}).get("allowed_hosts")
or request.config.getoption("--allowed-hosts")
or config.get("allowed_hosts")
)
if isinstance(allowed_hosts, str):
allowed_hosts = allowed_hosts.split(",")
return allowed_hosts


@pytest.fixture # type: ignore
def vcr_markers(request: SubRequest) -> List[Mark]:
"""All markers applied to the certain test together with cassette names associated with each marker."""
return list(request.node.iter_markers(name="vcr"))


@pytest.fixture(autouse=True) # type: ignore
def block_network(request: SubRequest, record_mode: str, vcr_markers: List[Mark]) -> Iterator[None]:
"""Block network access in tests except for "none" VCR recording mode."""
block_network = request.node.get_closest_marker(name="block_network")
if block_network is not None:
validate_block_network_mark(block_network)
if vcr_markers:
# Take `record_mode` with the most priority:
# - Explicit CLI option
# - The `vcr_config` fixture
# - The `vcr` mark
config = request.getfixturevalue("vcr_config")
merged_config = merge_kwargs(config, vcr_markers)
# If `--record-mode` was not explicitly passed in CLI, then take one from the merged config
if request.config.getoption("--record-mode") is None:
record_mode = merged_config.get("record_mode", "none")
if default_block and (not request.getfixturevalue("vcr_markers") or record_mode == "none"):
# If network blocking is enabled there is one exception - if VCR is in recording mode (any mode except "none")
if (block_network or request.config.getoption("--block-network")) and (not vcr_markers or record_mode == "none"):
allowed_hosts = request.getfixturevalue("allowed_hosts")
with network.blocking_context(allowed_hosts=allowed_hosts):
yield
else:
Expand Down
20 changes: 20 additions & 0 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,23 @@ def test_marker(default_cassette_name):
result = testdir.runpytest()
result.assert_outcomes(passed=1)
assert result.ret == 0


def test_lazy_vcr_config(testdir):
# When test does not involve VCR
testdir.makepyfile(
"""
import pytest
@pytest.fixture
def vcr_config():
raise RuntimeError("Should not run")
def test_marker():
pass
"""
)
# Then the `vcr_config` fixture should not be evaluated
result = testdir.runpytest()
result.assert_outcomes(passed=1)
assert result.ret == 0

0 comments on commit dafd141

Please sign in to comment.