diff --git a/httprunner/context.py b/httprunner/context.py index 7a160b5f..11d7736d 100644 --- a/httprunner/context.py +++ b/httprunner/context.py @@ -201,13 +201,8 @@ class Context(object): # format 1/2/3 check_value = self.eval_content(check_item) else: - try: - # format 4/5 - check_value = resp_obj.extract_field(check_item) - except exceptions.ParseResponseFailure: - msg = "failed to extract check item from response!\n" - msg += "response content: {}".format(resp_obj.content) - raise exceptions.ParseResponseFailure(msg) + # format 4/5 + check_value = resp_obj.extract_field(check_item) validator["check_value"] = check_value diff --git a/httprunner/exceptions.py b/httprunner/exceptions.py index 6323c896..29b743d7 100644 --- a/httprunner/exceptions.py +++ b/httprunner/exceptions.py @@ -12,7 +12,7 @@ class MyBaseFailure(BaseException): class ValidationFailure(MyBaseFailure): pass -class ParseResponseFailure(MyBaseFailure): +class ExtractFailure(MyBaseFailure): pass diff --git a/httprunner/response.py b/httprunner/response.py index 4d59e339..cf59715b 100644 --- a/httprunner/response.py +++ b/httprunner/response.py @@ -143,6 +143,9 @@ class ResponseObject(object): if isinstance(body, (dict, list)): # content = {"xxx": 123}, content.xxx return utils.query_json(body, sub_query) + elif sub_query.isdigit(): + # content = "abcdefg", content.3 => d + return utils.query_json(body, sub_query) else: # content = "abcdefg", content.xxx err_msg = u"ParamsError: Failed to extract attribute from response body! => {}\n".format(field) @@ -171,8 +174,8 @@ class ResponseObject(object): msg += "\t=> {}".format(value) logger.log_debug(msg) - # TODO: unify ParseResponseFailure type - except (exceptions.ParseResponseFailure, TypeError): + # TODO: remove except here + except (TypeError): logger.log_error("failed to extract field: {}".format(field)) raise diff --git a/httprunner/runner.py b/httprunner/runner.py index 55532ee9..ca7b49db 100644 --- a/httprunner/runner.py +++ b/httprunner/runner.py @@ -184,7 +184,7 @@ class Runner(object): try: self.context.validate(validators, resp_obj) except (exceptions.ParamsError, \ - exceptions.ValidationFailure, exceptions.ParseResponseFailure): + exceptions.ValidationFailure, exceptions.ExtractFailure): # log request err_req_msg = "request: \n" err_req_msg += "headers: {}\n".format(parsed_request.pop("headers", {})) diff --git a/httprunner/utils.py b/httprunner/utils.py index 2e67abb7..40592dfb 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -17,7 +17,7 @@ from datetime import datetime import yaml from httprunner import exceptions, logger -from httprunner.compat import OrderedDict, is_py2, is_py3 +from httprunner.compat import OrderedDict, is_py2, is_py3, str from requests.structures import CaseInsensitiveDict SECRET_KEY = "DebugTalk" @@ -186,20 +186,28 @@ def query_json(json_content, query, delimiter='.'): } @param (str) query "person.name.first_name" => "Leo" + "person.name.first_name.0" => "L" "person.cities.0" => "Guangzhou" @return queried result """ + raise_flag = False + response_body = u"from: {}\n".format(json_content) try: for key in query.split(delimiter): - if isinstance(json_content, list): + if isinstance(json_content, (list, str)): json_content = json_content[int(key)] elif isinstance(json_content, dict): json_content = json_content[key] else: - raise exceptions.ParseResponseFailure( - "response content is in text format! failed to query key {}!".format(key)) + raise_flag = True except (KeyError, ValueError, IndexError): - raise exceptions.ParseResponseFailure("failed to query json when extracting response!") + raise_flag = True + + if raise_flag: + err_msg = u"ExtractFailure: Failed to extract! => {}\n".format(query) + err_msg += response_body + logger.log_error(err_msg) + raise exceptions.ExtractFailure(err_msg) return json_content diff --git a/tests/test_response.py b/tests/test_response.py index 44cf333d..4a9ff9ac 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -300,7 +300,7 @@ class TestResponse(ApiServerUnittest): ] resp_obj = response.ResponseObject(resp) - with self.assertRaises(exceptions.ParseResponseFailure): + with self.assertRaises(exceptions.ExtractFailure): resp_obj.extract_response(extract_binds_list) extract_binds_list = [ @@ -308,7 +308,7 @@ class TestResponse(ApiServerUnittest): ] resp_obj = response.ResponseObject(resp) - with self.assertRaises(exceptions.ParseResponseFailure): + with self.assertRaises(exceptions.ExtractFailure): resp_obj.extract_response(extract_binds_list) def test_extract_response_json_string(self): @@ -387,5 +387,5 @@ class TestResponse(ApiServerUnittest): {"resp_content_body": "content.data.def"} ] resp_obj = response.ResponseObject(resp) - with self.assertRaises(exceptions.ParseResponseFailure): + with self.assertRaises(exceptions.ExtractFailure): resp_obj.extract_response(extract_binds_list) diff --git a/tests/test_utils.py b/tests/test_utils.py index dbdbe553..7b6e24dc 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -163,11 +163,11 @@ class TestUtils(ApiServerUnittest): self.assertEqual(result, 3) query = "ids.str_key" - with self.assertRaises(exceptions.ParseResponseFailure): + with self.assertRaises(exceptions.ExtractFailure): utils.query_json(json_content, query) query = "ids.5" - with self.assertRaises(exceptions.ParseResponseFailure): + with self.assertRaises(exceptions.ExtractFailure): utils.query_json(json_content, query) query = "person.age" @@ -175,7 +175,7 @@ class TestUtils(ApiServerUnittest): self.assertEqual(result, 29) query = "person.not_exist_key" - with self.assertRaises(exceptions.ParseResponseFailure): + with self.assertRaises(exceptions.ExtractFailure): utils.query_json(json_content, query) query = "person.cities.0" @@ -186,6 +186,10 @@ class TestUtils(ApiServerUnittest): result = utils.query_json(json_content, query) self.assertEqual(result, "Leo") + query = "person.name.first_name.0" + result = utils.query_json(json_content, query) + self.assertEqual(result, "L") + def test_get_uniform_comparator(self): self.assertEqual(utils.get_uniform_comparator("eq"), "equals") self.assertEqual(utils.get_uniform_comparator("=="), "equals")