diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index ce18d14d..2f85352a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,16 @@ # Release History +## 2.5.7 (2020-02-21) + +**Changed** + +- feat: validate with python script, display print message + +**Fixed** + +- fix: validate script missing indents in html report +- fix: validate with python script, display lineno error + ## 2.5.6 (2020-02-19) **Added** diff --git a/httprunner/__init__.py b/httprunner/__init__.py index b46ec9d4..a162fa0f 100644 --- a/httprunner/__init__.py +++ b/httprunner/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2.5.6" +__version__ = "2.5.7" __description__ = "One-stop solution for HTTP(S) testing." __all__ = ["__version__", "__description__"] diff --git a/httprunner/report/html/template.html b/httprunner/report/html/template.html index cef1ed19..8bbfc1bf 100644 --- a/httprunner/report/html/template.html +++ b/httprunner/report/html/template.html @@ -302,16 +302,16 @@ {% if validate_script %} - + - + {% if validate_script.check_result == "pass" %}
validate scriptexceptionvalidate scriptoutput
{{validate_script.validate_script | safe}}
{{validate_script.validate_script | safe}}
{% elif validate_script.check_result == "fail" %} {% endif %} - {{validate_script.exception}} + {{validate_script.output}}
diff --git a/httprunner/validator.py b/httprunner/validator.py index 8dad5ac6..eb2d52c4 100644 --- a/httprunner/validator.py +++ b/httprunner/validator.py @@ -1,5 +1,8 @@ # encoding: utf-8 +import sys +import traceback + from httprunner import exceptions, logger, parser @@ -60,54 +63,66 @@ class Validator(object): def validate_script(self, script): """ make validation with python script """ - validator_dict = { + result = { "validate_script": "
".join(script), - "check_result": "fail", - "exception": "" + "check_result": "pass", + "output": "" } script = "\n ".join(script) code = """ # encoding: utf-8 -try: +def run_validate_script(): {} -except Exception as ex: - import traceback - import sys - _type, _value, _tb = sys.exc_info() - # filename, lineno, name, line - _, _lineno, _, line_content = traceback.extract_tb(_tb, 1)[0] - - line_no = _lineno - 4 - - c_exception = _type.__name__ + "\\n" - c_exception += "\\tError line number: " + str(line_no) + "\\n" - c_exception += "\\tError line content: " + str(line_content) + "\\n" - - if _value.args: - c_exception += "\\tError description: " + str(_value) - else: - c_exception += "\\tError description: " + _type.__name__ - - raise _type(c_exception) """.format(script) + variables = { "status_code": self.resp_obj.status_code, "response_json": self.resp_obj.json, "response": self.resp_obj } variables.update(self.session_context.test_variables_mapping) + variables.update(globals()) try: - code = compile(code, '', 'exec') exec(code, variables) - validator_dict["check_result"] = "pass" - return validator_dict, "" + except SyntaxError as ex: + logger.log_warning("SyntaxError in python validate script: {}".format(ex)) + result["check_result"] = "fail" + result["output"] = "
".join([ + "ErrorMessage: {}".format(ex.msg), + "ErrorLine: {}".format(ex.lineno), + "ErrorText: {}".format(ex.text) + ]) + return result + + try: + # run python validate script + variables["run_validate_script"]() except Exception as ex: - validator_dict["check_result"] = "fail" - validator_dict["exception"] = "
".join(str(ex).splitlines()) - return validator_dict, str(ex) + logger.log_warning("run python validate script failed: {}".format(ex)) + result["check_result"] = "fail" + + _type, _value, _tb = sys.exc_info() + + _lineno = -1 + if _tb.tb_next: + _lineno = _tb.tb_next.tb_lineno + line_no = _lineno - 4 + elif len(traceback.extract_tb(_tb)) > 0: + # filename, lineno, name, line + _, _lineno, _, _ = traceback.extract_tb(_tb)[-1] + line_no = _lineno - 4 + else: + line_no = "N/A" + + result["output"] = "
".join([ + "ErrorType: {}".format(_type.__name__), + "ErrorLine: {}".format(line_no) + ]) + + return result def validate(self, validators): """ make validation with comparators @@ -125,12 +140,12 @@ except Exception as ex: if isinstance(validator, dict) and validator.get("type") == "python_script": script = self.session_context.eval_content(validator["script"]) - validator_dict, ex = self.validate_script(script) - if ex: + result = self.validate_script(script) + if result["check_result"] == "fail": validate_pass = False - failures.append(ex) + failures.append(result["output"]) - self.validation_results["validate_script"] = validator_dict + self.validation_results["validate_script"] = result continue if "validate_extractor" not in self.validation_results: diff --git a/pyproject.toml b/pyproject.toml index f11315b9..9dc88b7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "httprunner" -version = "2.5.6" +version = "2.5.7" description = "One-stop solution for HTTP(S) testing." license = "Apache-2.0" readme = "README.md"