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 %}
- | validate script | exception |
+ validate script | output |
- | {{validate_script.validate_script | safe}} |
+ {{validate_script.validate_script | safe}} |
{% if validate_script.check_result == "pass" %}
{% 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"