Package: pytest-recording
A pytest plugin that records network interactions in your tests via VCR.py.FeaturesStraightforwardpytest.mark.vcr, that reflectsVCR.use_cassettesAPI;Combining multiple VCR cassettes;Network access blocking;Therewriterecording mode that rewrites cassettes from scratch.Usageimportpytestimportrequests# cassettes/{module_name}/test_single.yaml will be used@pytest.mark.vcrdeftest_single():assertrequests.get("http://httpbin.org/get").text=='{"get": true}'# cassettes/{module_name}/example.yaml will be used@pytest.mark.default_cassette("example.yaml")@pytest.mark.vcrdeftest_default():assertrequests.get("http://httpbin.org/get").text=='{"get": true}'# these cassettes will be used in addition to the default one@pytest.mark.vcr("/path/to/ip.yaml","/path/to/get.yaml")deftest_multiple():assertrequests.get("http://httpbin.org/get").text=='{"get": true}'assertrequests.get("http://httpbin.org/ip").text=='{"ip": true}'Run your tests:pytest--record-mode=oncetest_network.pyDefault recording modepytest-recordinguses thenoneVCR recording mode by default to prevent unintentional network requests.
To allow them you need to pass a different recording mode (e.g.once) via the--record-modeCLI option to your test command.
See more information about available recording modes in theofficial VCR documentationConfigurationYou can provide the recording configuration with thevcr_configfixture, which could be any scope -session,package,module, orfunction. It should return a dictionary that will be passed directly toVCR.use_cassettesunder the hood.importpytest@pytest.fixture(scope="module")defvcr_config():return{"filter_headers":["authorization"]}For more granular control you need to pass these keyword arguments to individualpytest.mark.vcrmarks, and in this case
all arguments will be merged into a single dictionary with the following priority (low -> high):vcr_configfixtureall marks from the most broad scope (“session”) to the most narrow one (“function”)Example:importpytestpytestmark=[pytest.mark.vcr(ignore_localhost=True)]@pytest.fixture(scope="module")defvcr_config():return{"filter_headers":["authorization"]}@pytest.mark.vcr(filter_headers=[])deftest_one():...@pytest.mark.vcr(filter_query_parameters=["api_key"])deftest_two():...Resulting VCR configs for each test:test_one-{"ignore_localhost": True, "filter_headers": []}test_two-{"ignore_localhost": True, "filter_headers":["authorization"],"filter_query_parameters":["api_key"]}You can get access to the usedVCRinstance viapytest_recording_configurehook. It might be useful for registering
custom matchers, persisters, etc.:# conftest.pydefjurassic_matcher(r1,r2):assertr1.uri==r2.uriand"JURASSIC PARK"inr1.body,\"required string (JURASSIC PARK) not found in request body"defpytest_recording_configure(config,vcr):vcr.register_matcher("jurassic",jurassic_matcher)You can disable the VCR.py integration entirely by passing the--disable-recordingCLI option.Rewrite record modeIt is possible to rewrite a cassette from scratch and not extend it with new entries as it works now with theallrecord mode from VCR.py.However, it will rewrite only the default cassette and won’t touch extra cassettes.importpytest@pytest.fixture(scope="module")defvcr_config():return{"record_mode":"rewrite"}Or via command-line option:$pytest--record-mode=rewritetests/Blocking network accessTo have more confidence that your tests will not go over the wire, you can block it withpytest.mark.block_networkmark:importpytestimportrequests@pytest.mark.block_networkdeftest_multiple():assertrequests.get("http://httpbin.org/get").text=='{"get": true}'...# in case of accessRuntimeError:NetworkisdisabledBesides marks, the network access could be blocked globally with--block-networkcommand-line option.However, if VCR.py recording is enabled, the network is not blocked for tests withpytest.mark.vcr.Example:importpytestimportrequests@pytest.mark.vcrdeftest_multiple():assertrequests.get("http://httpbin.org/get").text=='{"get": true}'Runpytest:$pytest--record-mode=once--block-networktests/The network blocking feature supportssocket-based transports andpycurl.It is possible to allow access to specified hosts during network blocking:importpytestimportrequests@pytest.mark.block_network(allowed_hosts=["httpbin.*"])deftest_access():assertrequests.get("http://httpbin.org/get").text=='{"get": true}'withpytest.raises(RuntimeError,match=r"^Network is disabled$"):requests.get("http://example.com")Or via command-line option:$pytest--record-mode=once--block-network--allowed-hosts=httpbin.*,localhosttests/Or viavcr_configfixture:importpytest@pytest.fixture(autouse=True)defvcr_config():return{"allowed_hosts":["httpbin.*"]}Additional resourcesLooking for more examples? Check outthis articleaboutpytest-recording.ContributingTo run the tests:$tox-pallFor more information, take a look atour contributing guidePython supportPytest-recording supports:CPython 3.7, 3.8, 3.9, 3.10, 3.11, and 3.12PyPy 7 (3.6)LicenseThe code in this project is licensed underMIT license. By contributing topytest-recording, you agree that your contributions will be licensed under its MIT license.