Disallow "METHOD: url" in defaults

Otherwise it becomes difficult to manage on a few dimensions:

* the code to do it is complex
* the readability of the test is damaged

So now the default dict is validated. If it has uppercase keys a
GabbiFormatError is raised. A non-gabbi test for this has been
added, along with a test for duplicate METHOD keys in one test.
The existing method_shortcut.yaml tests have been updated to reflect
the change in defaults.

Some further cleanups on the tests are probably required and docs are
still missing, but this is almost working.
This commit is contained in:
Chris Dent
2015-09-11 17:00:22 +01:00
committed by FND
parent 1ad9713d9c
commit e647a843cd
3 changed files with 49 additions and 18 deletions

View File

@@ -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 # Set defaults from BASE_TESTS then update those defaults
# with any defaults set in the YAML file. # with any defaults set in the YAML file.
base_test_data = copy.deepcopy(case.HTTPTestCase.base_test) 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) test_update(base_test_data, defaults)
# Establish any fixture classes. # Establish any fixture classes.
@@ -178,6 +178,12 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
raise GabbiFormatError( raise GabbiFormatError(
'malformed test chunk "%s": %s' % (test_datum, exc)) 'malformed test chunk "%s": %s' % (test_datum, exc))
if not test['name']:
raise GabbiFormatError('Test name missing in a test in %s.'
% test_base_name)
test_name = '%s_%s' % (test_base_name,
test['name'].lower().replace(' ', '_'))
# use uppercase keys as HTTP method # use uppercase keys as HTTP method
method_key = None method_key = None
for key, val in six.iteritems(test): for key, val in six.iteritems(test):
@@ -185,7 +191,7 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
if method_key: if method_key:
raise GabbiFormatError( raise GabbiFormatError(
'duplicate method/URL directive in "%s"' % 'duplicate method/URL directive in "%s"' %
test_base_name) test_name)
test['method'] = key test['method'] = key
test['url'] = val test['url'] = val
@@ -193,12 +199,6 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
if method_key: if method_key:
del test[method_key] del test[method_key]
if not test['name']:
raise GabbiFormatError('Test name missing in a test in %s.'
% test_base_name)
test_name = '%s_%s' % (test_base_name,
test['name'].lower().replace(' ', '_'))
if not test['url']: if not test['url']:
raise GabbiFormatError('Test url missing in test %s.' raise GabbiFormatError('Test url missing in test %s.'
% test_name) % test_name)
@@ -231,3 +231,10 @@ def test_suite_from_yaml(loader, test_base_name, test_yaml, test_directory,
prior_test = this_test prior_test = this_test
return file_suite return file_suite
def _validate_defaults(default_dict):
if [key for key in default_dict if key.isupper()]:
raise GabbiFormatError(
'"METHOD: url" pairs not allowed in defaults')
return default_dict

View File

@@ -1,8 +1,7 @@
defaults:
POST: /somewhere
tests: tests:
- name: defaults check - name: simple POST
POST: /somewhere
data: data:
cow: barn cow: barn
request_headers: request_headers:
@@ -10,8 +9,8 @@ tests:
response_json_paths: response_json_paths:
$.cow: barn $.cow: barn
- name: altered defaults - name: POST with query
url: /somewhere?chicken=coop POST: /somewhere?chicken=coop
data: data:
cow: barn cow: barn
request_headers: request_headers:
@@ -20,7 +19,7 @@ tests:
$.cow: barn $.cow: barn
$.chicken[0]: coop $.chicken[0]: coop
- name: overridden defaults - name: simple GET
GET: / GET: /
ssl: True ssl: True
response_headers: response_headers:
@@ -34,7 +33,10 @@ tests:
x-gabbi-method: IMAGINARY x-gabbi-method: IMAGINARY
x-gabbi-url: $SCHEME://$NETLOC/ x-gabbi-url: $SCHEME://$NETLOC/
- name: duplicate shortcut # Can't do this because format validation is during test generation not
GET: / # test running. xfail only works during test running :(
POST: / # See gabbi/tests/test_driver for a test of this.
xfail: true # - name: duplicate shortcut
# GET: /
# POST: /
# xfail: true

View File

@@ -111,3 +111,25 @@ class DriverTest(unittest.TestCase):
'localhost', 80, None, None) 'localhost', 80, None, None)
self.assertIn("Invalid test keys used in test foo_simple:", self.assertIn("Invalid test keys used in test foo_simple:",
str(failure.exception)) 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)
)