Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kiwicom/pytest-recording
A pytest plugin that allows recording network interactions via VCR.py
https://github.com/kiwicom/pytest-recording
cassettes hacktoberfest pytest python testing vcr
Last synced: 3 months ago
JSON representation
A pytest plugin that allows recording network interactions via VCR.py
- Host: GitHub
- URL: https://github.com/kiwicom/pytest-recording
- Owner: kiwicom
- License: mit
- Created: 2019-07-16T14:57:52.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-07-09T10:09:24.000Z (4 months ago)
- Last Synced: 2024-07-10T10:03:41.479Z (4 months ago)
- Topics: cassettes, hacktoberfest, pytest, python, testing, vcr
- Language: Python
- Homepage:
- Size: 209 KB
- Stars: 397
- Watchers: 4
- Forks: 33
- Open Issues: 26
-
Metadata Files:
- Readme: README.rst
- Contributing: CONTRIBUTING.rst
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
pytest-recording
================|codecov| |Build| |Version| |Python versions| |License|
A pytest plugin that records network interactions in your tests via VCR.py.
Features
--------- Straightforward ``pytest.mark.vcr``, that reflects ``VCR.use_cassettes`` API;
- Combining multiple VCR cassettes;
- Network access blocking;
- The ``rewrite`` recording mode that rewrites cassettes from scratch.Installation
------------This project can be installed via pip:
.. code:: bash
pip install pytest-recording
⚠️This project is not compatible with `pytest-vcr`, make sure to uninstall before ⚠️
Usage
-----.. code:: python
import pytest
import requests# cassettes/{module_name}/test_single.yaml will be used
@pytest.mark.vcr
def test_single():
assert requests.get("http://httpbin.org/get").text == '{"get": true}'# cassettes/{module_name}/example.yaml will be used
@pytest.mark.default_cassette("example.yaml")
@pytest.mark.vcr
def test_default():
assert requests.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")
def test_multiple():
assert requests.get("http://httpbin.org/get").text == '{"get": true}'
assert requests.get("http://httpbin.org/ip").text == '{"ip": true}'# Make assertions based on the cassette calls/responses:
@pytest.mark.vcr
def test_call_count(vcr):
assert requests.get("http://httpbin.org/get").text == '{"get": true}'
assert requests.get("http://httpbin.org/ip").text == '{"ip": true}'
# See https://vcrpy.readthedocs.io/en/latest/advanced.html for more info
# about the Cassette object:
assert vcr.play_count == 2Run your tests:
.. code:: bash
pytest --record-mode=once test_network.py
Default recording mode
~~~~~~~~~~~~~~~~~~~~~~``pytest-recording`` uses the ``none`` VCR 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-mode`` CLI option to your test command.
See more information about available recording modes in the `official VCR documentation `_Configuration
~~~~~~~~~~~~~You can provide the recording configuration with the ``vcr_config`` fixture, which could be any scope - ``session``,
``package``, ``module``, or ``function``. It should return a dictionary that will be passed directly to ``VCR.use_cassettes``
under the hood... code:: python
import pytest
@pytest.fixture(scope="module")
def vcr_config():
return {"filter_headers": ["authorization"]}For more granular control you need to pass these keyword arguments to individual ``pytest.mark.vcr`` marks, and in this case
all arguments will be merged into a single dictionary with the following priority (low -> high):- ``vcr_config`` fixture
- all marks from the most broad scope ("session") to the most narrow one ("function")Example:
.. code:: python
import pytest
pytestmark = [pytest.mark.vcr(ignore_localhost=True)]
@pytest.fixture(scope="module")
def vcr_config():
return {"filter_headers": ["authorization"]}@pytest.mark.vcr(filter_headers=[])
def test_one():
...@pytest.mark.vcr(filter_query_parameters=["api_key"])
def test_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 used ``VCR`` instance via ``pytest_recording_configure`` hook. It might be useful for registering
custom matchers, persisters, etc.:.. code:: python
# conftest.py
def jurassic_matcher(r1, r2):
assert r1.uri == r2.uri and "JURASSIC PARK" in r1.body, \
"required string (JURASSIC PARK) not found in request body"def pytest_recording_configure(config, vcr):
vcr.register_matcher("jurassic", jurassic_matcher)You can disable the VCR.py integration entirely by passing the ``--disable-recording`` CLI option.
Rewrite record mode
~~~~~~~~~~~~~~~~~~~It is possible to rewrite a cassette from scratch and not extend it with new entries as it works now with the ``all`` record mode from VCR.py.
However, it will rewrite only the default cassette and won't touch extra cassettes.
.. code:: python
import pytest
@pytest.fixture(scope="module")
def vcr_config():
return {"record_mode": "rewrite"}Or via command-line option:
.. code:: bash
$ pytest --record-mode=rewrite tests/
Blocking network access
~~~~~~~~~~~~~~~~~~~~~~~To have more confidence that your tests will not go over the wire, you can block it with ``pytest.mark.block_network`` mark:
.. code:: python
import pytest
import requests@pytest.mark.block_network
def test_multiple():
assert requests.get("http://httpbin.org/get").text == '{"get": true}'...
# in case of access
RuntimeError: Network is disabledBesides marks, the network access could be blocked globally with ``--block-network`` command-line option.
However, if VCR.py recording is enabled, the network is not blocked for tests with ``pytest.mark.vcr``.
Example:
.. code:: python
import pytest
import requests@pytest.mark.vcr
def test_multiple():
assert requests.get("http://httpbin.org/get").text == '{"get": true}'Run ``pytest``:
.. code:: bash
$ pytest --record-mode=once --block-network tests/
The network blocking feature supports ``socket``-based transports and ``pycurl``.
It is possible to allow access to specified hosts during network blocking:
.. code:: python
import pytest
import requests@pytest.mark.block_network(allowed_hosts=["httpbin.*"])
def test_access():
assert requests.get("http://httpbin.org/get").text == '{"get": true}'
with pytest.raises(RuntimeError, match=r"^Network is disabled$"):
requests.get("http://example.com")Or via command-line option:
.. code:: bash
$ pytest --record-mode=once --block-network --allowed-hosts=httpbin.*,localhost tests/
Or via `vcr_config` fixture:
.. code:: python
import pytest
@pytest.fixture(autouse=True)
def vcr_config():
return {"allowed_hosts": ["httpbin.*"]}Additional resources
--------------------Looking for more examples? Check out `this article `_ about ``pytest-recording``.
Contributing
------------To run the tests:
.. code:: bash
$ tox -p all
For more information, take a look at `our contributing guide `_
Python support
--------------Pytest-recording supports:
- CPython 3.7, 3.8, 3.9, 3.10, 3.11, and 3.12
- PyPy 7 (3.6)License
-------The code in this project is licensed under `MIT license`_. By contributing to ``pytest-recording``, you agree that your contributions will be licensed under its MIT license.
.. |codecov| image:: https://codecov.io/gh/kiwicom/pytest-recording/branch/master/graph/badge.svg
:target: https://codecov.io/gh/kiwicom/pytest-recording
.. |Build| image:: https://github.com/kiwicom/pytest-recording/actions/workflows/build.yml/badge.svg
:target: https://github.com/kiwicom/pytest-recording/actions?query=workflow%3Abuild
.. |Version| image:: https://img.shields.io/pypi/v/pytest-recording.svg
:target: https://pypi.org/project/pytest-recording/
.. |Python versions| image:: https://img.shields.io/pypi/pyversions/pytest-recording.svg
:target: https://pypi.org/project/pytest-recording/
.. |License| image:: https://img.shields.io/pypi/l/pytest-recording.svg
:target: https://opensource.org/licenses/MIT.. _MIT license: https://opensource.org/licenses/MIT