diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7209ec56..aa9fca22 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -5,6 +5,7 @@ **Added** - feat: implement step setup/teardown hooks +- feat: support alter response in teardown hooks **Fixed** diff --git a/examples/httpbin/basic_test.py b/examples/httpbin/basic_test.py index bfa47499..4fe82d84 100644 --- a/examples/httpbin/basic_test.py +++ b/examples/httpbin/basic_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/httpbin/basic.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/httpbin/debugtalk.py b/examples/httpbin/debugtalk.py index b31deacc..ef78aee0 100644 --- a/examples/httpbin/debugtalk.py +++ b/examples/httpbin/debugtalk.py @@ -126,7 +126,7 @@ def setup_hook_httpntlmauth(request): def alter_response(response): response.status_code = 500 response.headers["Content-Type"] = "html/text" - response.json["headers"]["Host"] = "127.0.0.1:8888" + response.body["headers"]["Host"] = "127.0.0.1:8888" response.new_attribute = "new_attribute_value" response.new_attribute_dict = {"key": 123} diff --git a/examples/httpbin/hooks.yml b/examples/httpbin/hooks.yml index 770d9926..250a7a8f 100644 --- a/examples/httpbin/hooks.yml +++ b/examples/httpbin/hooks.yml @@ -31,7 +31,7 @@ teststeps: teardown_hooks: - ${alter_response($response)} validate: - - eq: ["status_code", 200] - # TODO: implement hooks -# - eq: [body.headers."Content-Type", "html/text"] - - eq: [body.headers.Host, "httpbin.org"] + - eq: ["status_code", 500] + - eq: [headers."Content-Type", "html/text"] + - eq: [body.headers."Content-Type", "application/json"] + - eq: [body.headers.Host, "127.0.0.1:8888"] diff --git a/examples/httpbin/hooks_test.py b/examples/httpbin/hooks_test.py index a10f629e..5ae2da61 100644 --- a/examples/httpbin/hooks_test.py +++ b/examples/httpbin/hooks_test.py @@ -24,8 +24,10 @@ class TestCaseHooks(HttpRunner): .get("/headers") .teardown_hook("${alter_response($response)}") .validate() - .assert_equal("status_code", 200) - .assert_equal("body.headers.Host", "httpbin.org") + .assert_equal("status_code", 500) + .assert_equal('headers."Content-Type"', "html/text") + .assert_equal('body.headers."Content-Type"', "application/json") + .assert_equal("body.headers.Host", "127.0.0.1:8888") ), ] diff --git a/examples/httpbin/load_image_test.py b/examples/httpbin/load_image_test.py index cca17a7c..cd21fb69 100644 --- a/examples/httpbin/load_image_test.py +++ b/examples/httpbin/load_image_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/httpbin/load_image.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/httpbin/upload_test.py b/examples/httpbin/upload_test.py index 6ed390a8..fa100f85 100644 --- a/examples/httpbin/upload_test.py +++ b/examples/httpbin/upload_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/httpbin/upload.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/httpbin/validate_test.py b/examples/httpbin/validate_test.py index 093d5075..281a94fb 100644 --- a/examples/httpbin/validate_test.py +++ b/examples/httpbin/validate_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/httpbin/validate.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_functions_test.py b/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_functions_test.py index da34ceca..0944f1c5 100644 --- a/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_functions_test.py +++ b/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_functions_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/request_with_functions.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_testcase_reference_test.py b/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_testcase_reference_test.py index af45b5ba..23fc387a 100644 --- a/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_testcase_reference_test.py +++ b/examples/postman_echo/request_methods/demo_testsuite_yml/request_with_testcase_reference_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/request_with_testcase_reference.yml import os diff --git a/examples/postman_echo/request_methods/hardcode_test.py b/examples/postman_echo/request_methods/hardcode_test.py index ffa7d91a..cc1ddb3b 100644 --- a/examples/postman_echo/request_methods/hardcode_test.py +++ b/examples/postman_echo/request_methods/hardcode_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/hardcode.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/postman_echo/request_methods/request_with_functions_test.py b/examples/postman_echo/request_methods/request_with_functions_test.py index 159d93b6..5ee630e0 100644 --- a/examples/postman_echo/request_methods/request_with_functions_test.py +++ b/examples/postman_echo/request_methods/request_with_functions_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/request_with_functions.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/postman_echo/request_methods/request_with_testcase_reference_test.py b/examples/postman_echo/request_methods/request_with_testcase_reference_test.py index ece17405..27b7fcb0 100644 --- a/examples/postman_echo/request_methods/request_with_testcase_reference_test.py +++ b/examples/postman_echo/request_methods/request_with_testcase_reference_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/request_with_testcase_reference.yml import os diff --git a/examples/postman_echo/request_methods/request_with_variables_test.py b/examples/postman_echo/request_methods/request_with_variables_test.py index aab91e97..5f8c0484 100644 --- a/examples/postman_echo/request_methods/request_with_variables_test.py +++ b/examples/postman_echo/request_methods/request_with_variables_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/request_with_variables.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/postman_echo/request_methods/validate_with_functions_test.py b/examples/postman_echo/request_methods/validate_with_functions_test.py index 5a730f1e..185896af 100644 --- a/examples/postman_echo/request_methods/validate_with_functions_test.py +++ b/examples/postman_echo/request_methods/validate_with_functions_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/validate_with_functions.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/examples/postman_echo/request_methods/validate_with_variables_test.py b/examples/postman_echo/request_methods/validate_with_variables_test.py index 26c2467f..05daa1ae 100644 --- a/examples/postman_echo/request_methods/validate_with_variables_test.py +++ b/examples/postman_echo/request_methods/validate_with_variables_test.py @@ -1,4 +1,4 @@ -# NOTE: Generated By HttpRunner v3.0.9 +# NOTE: Generated By HttpRunner v3.0.10 # FROM: examples/postman_echo/request_methods/validate_with_variables.yml from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase diff --git a/httprunner/response.py b/httprunner/response.py index 41171271..1efa945d 100644 --- a/httprunner/response.py +++ b/httprunner/response.py @@ -4,6 +4,7 @@ import jmespath import requests from loguru import logger +from httprunner import exceptions from httprunner.exceptions import ValidationFailure, ParamsError from httprunner.parser import parse_data, parse_string_value, get_mapping_function from httprunner.models import VariablesMapping, Validators, FunctionsMapping @@ -109,20 +110,36 @@ class ResponseObject(object): """ self.resp_obj = resp_obj - - try: - body = resp_obj.json() - except ValueError: - body = resp_obj.content - - self.resp_obj_meta = { - "status_code": resp_obj.status_code, - "headers": resp_obj.headers, - "cookies": dict(resp_obj.cookies), - "body": body, - } self.validation_results: Dict = {} + def __getattr__(self, key): + if key in ["json", "content", "body"]: + try: + value = self.resp_obj.json() + except ValueError: + value = self.resp_obj.content + elif key == "cookies": + value = self.resp_obj.cookies.get_dict() + else: + try: + value = getattr(self.resp_obj, key) + except AttributeError: + err_msg = "ResponseObject does not have attribute: {}".format(key) + logger.error(err_msg) + raise exceptions.ParamsError(err_msg) + + self.__dict__[key] = value + return value + + @property + def resp_obj_meta(self): + return { + "status_code": self.status_code, + "headers": self.headers, + "cookies": self.cookies, + "body": self.body, + } + def extract(self, extractors: Dict[Text, Text]) -> Dict[Text, Any]: if not extractors: return {} diff --git a/httprunner/testcase.py b/httprunner/testcase.py index 5ceb4efc..03f8e68a 100644 --- a/httprunner/testcase.py +++ b/httprunner/testcase.py @@ -265,7 +265,9 @@ class RequestWithOptionalArgs(object): self.__step_context.request.upload.update(file_info) return self - def teardown_hook(self, hook: Text, assign_var_name: Text = None) -> "RequestWithOptionalArgs": + def teardown_hook( + self, hook: Text, assign_var_name: Text = None + ) -> "RequestWithOptionalArgs": if assign_var_name: self.__step_context.teardown_hooks.append({assign_var_name: hook}) else: