Merge pull request #89 from cdent/method-shortcut
added optional shortcut for specifying HTTP method and URL
This commit is contained in:
commit
84a89c4962
@ -3,13 +3,20 @@ Test Format
|
||||
|
||||
Gabbi tests are expressed in YAML containing an HTTP request and an
|
||||
expected response. Each YAML file is an ordered sequence of requests.
|
||||
The bare minimum YAML file for a single request is::
|
||||
A minimal YAML file for a single request is::
|
||||
|
||||
tests:
|
||||
- name: the name of a test
|
||||
GET: /
|
||||
|
||||
This is :ref:`short <method-shortcut>` for::
|
||||
|
||||
tests:
|
||||
- name: the name of a test
|
||||
method: GET
|
||||
url: /
|
||||
|
||||
This will make a request to ``/`` on whatever the configured
|
||||
This will make a ``GET`` request to ``/`` on whatever the configured
|
||||
:doc:`host` is. The test will pass if the status of the HTTP response
|
||||
is ``200``.
|
||||
|
||||
@ -90,6 +97,21 @@ Many of these items allow substitutions (explained below).
|
||||
This makes it possible to poll for a resource created via an
|
||||
asynchronous request. Use with caution.
|
||||
|
||||
.. _method-shortcut:
|
||||
|
||||
Note that it's possible to combine ``method`` and ``url`` into a single
|
||||
statement by exchanging the ``url`` key for the actual method::
|
||||
|
||||
method: PATCH
|
||||
url: /
|
||||
|
||||
corresponds to::
|
||||
|
||||
PATCH: /
|
||||
|
||||
Any uppercase key is considered an HTTP method, there is no pre-defined
|
||||
list of approved methods.
|
||||
|
||||
The ``response_*`` items are examples of Response Handlers. Additional
|
||||
handlers may be created by test authors for specific use cases. See
|
||||
:doc:`handlers` for more information.
|
||||
|
@ -153,7 +153,7 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
|
||||
# Set defaults from BASE_TESTS then update those defaults
|
||||
# with any defaults set in the YAML file.
|
||||
base_test_data = copy.deepcopy(case.HTTPTestCase.base_test)
|
||||
defaults = test_yaml.get('defaults', {})
|
||||
defaults = _validate_defaults(test_yaml.get('defaults', {}))
|
||||
test_update(base_test_data, defaults)
|
||||
|
||||
# Establish any fixture classes.
|
||||
@ -184,6 +184,21 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
|
||||
test_name = '%s_%s' % (test_base_name,
|
||||
test['name'].lower().replace(' ', '_'))
|
||||
|
||||
# use uppercase keys as HTTP method
|
||||
method_key = None
|
||||
for key, val in six.iteritems(test):
|
||||
if _is_method_shortcut(key):
|
||||
if method_key:
|
||||
raise GabbiFormatError(
|
||||
'duplicate method/URL directive in "%s"' %
|
||||
test_name)
|
||||
|
||||
test['method'] = key
|
||||
test['url'] = val
|
||||
method_key = key
|
||||
if method_key:
|
||||
del test[method_key]
|
||||
|
||||
if not test['url']:
|
||||
raise GabbiFormatError('Test url missing in test %s.'
|
||||
% test_name)
|
||||
@ -216,3 +231,18 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
|
||||
prior_test = this_test
|
||||
|
||||
return file_suite
|
||||
|
||||
|
||||
def _validate_defaults(defaults):
|
||||
"""Ensure default test settings are acceptable
|
||||
|
||||
Raises GabbiFormatError for invalid settings.
|
||||
"""
|
||||
if any(_is_method_shortcut(key) for key in defaults):
|
||||
raise GabbiFormatError(
|
||||
'"METHOD: url" pairs not allowed in defaults')
|
||||
return defaults
|
||||
|
||||
|
||||
def _is_method_shortcut(key):
|
||||
return key.isupper()
|
||||
|
42
gabbi/gabbits_intercept/method_shortcut.yaml
Normal file
42
gabbi/gabbits_intercept/method_shortcut.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
tests:
|
||||
- name: simple POST
|
||||
POST: /somewhere
|
||||
data:
|
||||
cow: barn
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
response_json_paths:
|
||||
$.cow: barn
|
||||
|
||||
- name: POST with query
|
||||
POST: /somewhere?chicken=coop
|
||||
data:
|
||||
cow: barn
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
response_json_paths:
|
||||
$.cow: barn
|
||||
$.chicken[0]: coop
|
||||
|
||||
- name: simple GET
|
||||
GET: /
|
||||
ssl: True
|
||||
response_headers:
|
||||
x-gabbi-url: https://$NETLOC/
|
||||
|
||||
- name: arbitrary method
|
||||
IMAGINARY: /
|
||||
status: 405
|
||||
response_headers:
|
||||
allow: GET, PUT, POST, DELETE, PATCH
|
||||
x-gabbi-method: IMAGINARY
|
||||
x-gabbi-url: $SCHEME://$NETLOC/
|
||||
|
||||
# Can't do this because format validation is during test generation not
|
||||
# test running. xfail only works during test running :(
|
||||
# See gabbi/tests/test_driver for a test of this.
|
||||
# - name: duplicate shortcut
|
||||
# GET: /
|
||||
# POST: /
|
||||
# xfail: true
|
@ -111,3 +111,25 @@ class DriverTest(unittest.TestCase):
|
||||
'localhost', 80, None, None)
|
||||
self.assertIn("Invalid test keys used in test foo_simple:",
|
||||
str(failure.exception))
|
||||
|
||||
def test_method_url_pair_format_error(self):
|
||||
test_yaml = {'defaults': {'GET': '/foo'}, 'tests': []}
|
||||
with self.assertRaises(driver.GabbiFormatError) as failure:
|
||||
driver.test_suite_from_yaml(self.loader, 'foo', test_yaml, '.',
|
||||
'localhost', 80, None, None)
|
||||
self.assertIn('"METHOD: url" pairs not allowed in defaults',
|
||||
str(failure.exception))
|
||||
|
||||
def test_method_url_pair_duplication_format_error(self):
|
||||
test_yaml = {'tests': [{
|
||||
'GET': '/',
|
||||
'POST': '/',
|
||||
'name': 'duplicate methods',
|
||||
}]}
|
||||
with self.assertRaises(driver.GabbiFormatError) as failure:
|
||||
driver.test_suite_from_yaml(self.loader, 'foo', test_yaml, '.',
|
||||
'localhost', 80, None, None)
|
||||
self.assertIn(
|
||||
'duplicate method/URL directive in "foo_duplicate_methods"',
|
||||
str(failure.exception)
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user