Allow users to specify request matchers in Betamax

The default matchers for Betamax are decent enough for simple GET
requests. However, when POSTing data, extra matchers are often required
in order to provide quality matching of a request being made to one that
has already been recorded.

Change-Id: I801e52a028e9293cf28c6894b2fe10384cce3267
Closes-bug: #1671111
This commit is contained in:
Ian Cordasco
2017-03-08 11:55:26 -06:00
parent 0cd0191818
commit e290dd3015
2 changed files with 67 additions and 2 deletions

View File

@@ -29,7 +29,38 @@ class BetamaxFixture(fixtures.Fixture):
def __init__(self, cassette_name, cassette_library_dir=None,
serializer=None, record=False,
pre_record_hook=hooks.pre_record_hook,
serializer_name=None):
serializer_name=None, request_matchers=None):
"""Configure Betamax for the test suite.
:param str cassette_name:
This is simply the name of the cassette without any file extension
or containing directory. For example, to generate
``keystoneauth1/tests/unit/data/example.yaml``, one would pass
only ``example``.
:param str cassette_library_dir:
This is the directory that will contain all cassette files. In
``keystoneauth1/tests/unit/data/example.yaml`` you would pass
``keystoneauth1/tests/unit/data/``.
:param serializer:
A class that implements the Serializer API in Betamax. See also:
https://betamax.readthedocs.io/en/latest/serializers.html
:param record:
The Betamax record mode to use. If ``False`` (the default), then
Betamax will not record anything. For more information about
record modes, see:
https://betamax.readthedocs.io/en/latest/record_modes.html
:param callable pre_record_hook:
Function or callable to use to perform some handling of the
request or response data prior to saving it to disk.
:param str serializer_name:
The name of a serializer already registered with Betamax to use
to handle cassettes. For example, if you want to use the default
Betamax serializer, you would pass ``'json'`` to this parameter.
:param list request_matchers:
The list of request matcher names to use with Betamax. Betamax's
default list is used if none are specified. See also:
https://betamax.readthedocs.io/en/latest/matchers.html
"""
self.cassette_library_dir = cassette_library_dir
self.record = record
self.cassette_name = cassette_name
@@ -41,9 +72,22 @@ class BetamaxFixture(fixtures.Fixture):
self.serializer = serializer
self._serializer_name = serializer_name
self.pre_record_hook = pre_record_hook
self.use_cassette_kwargs = {}
if request_matchers is not None:
self.use_cassette_kwargs['match_requests_on'] = request_matchers
@property
def serializer_name(self):
"""Determine the name of the selected serializer.
If a class was specified, use the name attribute to generate this,
otherwise, use the serializer_name parameter from ``__init__``.
:returns:
Name of the serializer
:rtype:
str
"""
if self.serializer:
return self.serializer.name
return self._serializer_name
@@ -84,7 +128,8 @@ def _construct_session_with_betamax(fixture, session_obj=None):
fixture.recorder.use_cassette(fixture.cassette_name,
serialize_with=serializer,
record=record)
record=record,
**fixture.use_cassette_kwargs)
fixture.recorder.start()
fixture.addCleanup(fixture.recorder.stop)

View File

@@ -103,3 +103,23 @@ class TestBetamaxFixtureSerializerBehaviour(testtools.TestCase):
self.assertIs(serializer.YamlJsonSerializer, fixture.serializer)
self.assertEqual('yamljson', fixture.serializer_name)
def test_no_request_matchers_provided(self):
fixture = keystoneauth_betamax.BetamaxFixture(
cassette_name='fake',
cassette_library_dir='keystoneauth1/tests/unit/data',
)
self.assertDictEqual({}, fixture.use_cassette_kwargs)
def test_request_matchers(self):
fixture = keystoneauth_betamax.BetamaxFixture(
cassette_name='fake',
cassette_library_dir='keystoneauth1/tests/unit/data',
request_matchers=['method', 'uri', 'json-body'],
)
self.assertDictEqual(
{'match_requests_on': ['method', 'uri', 'json-body']},
fixture.use_cassette_kwargs,
)