feat: log detailed request & response when failed

This commit is contained in:
debugtalk
2020-04-21 22:42:14 +08:00
parent 8f3cb320a4
commit 3a012f012e
2 changed files with 47 additions and 8 deletions

View File

@@ -4,7 +4,7 @@ import jmespath
import requests import requests
from loguru import logger from loguru import logger
from httprunner.v3.exceptions import ValidationFailure from httprunner.v3.exceptions import ValidationFailure, ParamsError
from httprunner.v3.parser import parse_data, parse_string_value, get_mapping_function from httprunner.v3.parser import parse_data, parse_string_value, get_mapping_function
from httprunner.v3.schema import VariablesMapping, Validators, FunctionsMapping from httprunner.v3.schema import VariablesMapping, Validators, FunctionsMapping
from httprunner.v3.validator import uniform_validator from httprunner.v3.validator import uniform_validator
@@ -19,6 +19,7 @@ class ResponseObject(object):
resp_obj (instance): requests.Response instance resp_obj (instance): requests.Response instance
""" """
self.resp_obj = resp_obj
self.resp_obj_meta = { self.resp_obj_meta = {
"status_code": resp_obj.status_code, "status_code": resp_obj.status_code,
"headers": resp_obj.headers, "headers": resp_obj.headers,
@@ -26,6 +27,22 @@ class ResponseObject(object):
} }
self.validation_results = {} self.validation_results = {}
def __getattr__(self, key):
try:
if key == "json":
value = self.resp_obj.json()
elif key == "cookies":
value = self.resp_obj.cookies.get_dict()
else:
value = getattr(self.resp_obj, key)
self.__dict__[key] = value
return value
except AttributeError:
err_msg = f"ResponseObject does not have attribute: {key}"
logger.error(err_msg)
raise ParamsError(err_msg)
def extract(self, extractors: Dict[Text, Text]) -> Dict[Text, Any]: def extract(self, extractors: Dict[Text, Text]) -> Dict[Text, Any]:
if not extractors: if not extractors:
return {} return {}
@@ -90,13 +107,11 @@ class ResponseObject(object):
validate_pass = False validate_pass = False
validator_dict["check_result"] = "fail" validator_dict["check_result"] = "fail"
validate_msg += "\t==> fail" validate_msg += "\t==> fail"
validate_msg += "\n{}({}) {} {}({})".format( validate_msg += f"\n" \
check_value, f"check_item: {check_item}\n" \
type(check_value).__name__, f"check_value: {check_value}({type(check_value).__name__})\n" \
assert_method, f"assert_method: {assert_method}\n" \
expect_value, f"expect_value: {expect_value}({type(expect_value).__name__})"
type(expect_value).__name__
)
logger.error(validate_msg) logger.error(validate_msg)
failures.append(validate_msg) failures.append(validate_msg)

View File

@@ -2,6 +2,7 @@ from typing import List
from loguru import logger from loguru import logger
from httprunner import utils
from httprunner.client import HttpSession from httprunner.client import HttpSession
from httprunner.v3.exceptions import ValidationFailure from httprunner.v3.exceptions import ValidationFailure
from httprunner.v3.parser import build_url, parse_data, parse_variables_mapping from httprunner.v3.parser import build_url, parse_data, parse_variables_mapping
@@ -52,6 +53,28 @@ class TestCaseRunner(object):
resp = self.session.request(method, url, **parsed_request_dict) resp = self.session.request(method, url, **parsed_request_dict)
resp_obj = ResponseObject(resp) resp_obj = ResponseObject(resp)
def log_req_resp_details():
err_msg = "\n{} DETAILED REQUEST & RESPONSE {}\n".format("*" * 32, "*" * 32)
# log request
err_msg += "====== request details ======\n"
err_msg += f"url: {url}\n"
err_msg += f"method: {method}\n"
headers = parsed_request_dict.pop("headers", {})
err_msg += f"headers: {headers}\n"
for k, v in parsed_request_dict.items():
v = utils.omit_long_data(v)
err_msg += f"{k}: {repr(v)}\n"
err_msg += "\n"
# log response
err_msg += "====== response details ======\n"
err_msg += f"status_code: {resp_obj.status_code}\n"
err_msg += f"headers: {resp_obj.headers}\n"
err_msg += f"body: {repr(resp_obj.text)}\n"
logger.error(err_msg)
# extract # extract
extractors = step.extract extractors = step.extract
extract_mapping = resp_obj.extract(extractors) extract_mapping = resp_obj.extract(extractors)
@@ -64,6 +87,7 @@ class TestCaseRunner(object):
try: try:
resp_obj.validate(validators, variables_mapping, self.config.functions) resp_obj.validate(validators, variables_mapping, self.config.functions)
except ValidationFailure: except ValidationFailure:
log_req_resp_details()
raise raise
finally: finally:
self.validation_results = resp_obj.validation_results self.validation_results = resp_obj.validation_results