responses icon indicating copy to clipboard operation
responses copied to clipboard

Feedback on responses._recorder / How to make it better

Open last-partizan opened this issue 1 year ago • 1 comments

This is awesome feature, and I started using it right away.

But, it's tedious to have separate code for creating responses. So, I'm using following plugin:

It allows to run pytest --update-responses and they will be saved to a file, and loaded when used without this argument.

Maybe, include this as plugin? I can make PR adding this, so we can make proper code review.

from __future__ import annotations

import pytest
import responses
from _pytest.config.argparsing import Parser
from pytest_cases import fixture
from responses._recorder import recorder


def pytest_addoption(parser: Parser):
    group = parser.getgroup("responses")
    group.addoption(
        "--update-responses",
        action="store_true",
        dest="update_responses",
        default=False,
        help="Don't mock responses, instead write actual responses to snapshot files.",
    )


@fixture
def mocked_responses():
    with responses.RequestsMock() as rsps:
        yield rsps


@fixture
def responses_snapshot(request: pytest.FixtureRequest):
    """
    Before using response you need to write snapshots.

    Run with `pytest --update-responses`.

    https://github.com/getsentry/responses#record-responses-to-files
    """

    update = request.config.getoption("update_responses")
    snapshot = _get_snapshot_file(request)

    if update:
        with recorder as r:
            yield r
            recorder.dump_to_file(
                file_path=snapshot,
                registered=r.get_registry().registered,
            )
    else:
        with responses.RequestsMock() as r:
            r._add_from_file(snapshot)
            yield r


def _get_snapshot_file(request: pytest.FixtureRequest):
    f = request.node.name.replace("[", "-").replace("]", "")
    p = request.path.parent / "__responses__/"
    p.mkdir(exist_ok=True)
    return p / f"{f}.yaml"

last-partizan avatar Oct 06 '24 15:10 last-partizan

This

f = request.node.name.replace("[", "-").replace("]", "")

might produce a filename which is too long. A better alternative is perhaps to hash the request.node.nodeid and use that as a file stem.

nschloe avatar Mar 28 '25 11:03 nschloe