mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +08:00
Merge pull request #823 from httprunner/leo_dev
2.4.9 **Added** - test: add unittest for cli **Changed** - change: html report name defaults to be in UTC ISO 8601 format **Fixed** - fix: display validators in report when validate raised exception - fix: eval validator python script before validating - fix: do not strip string content when preparing lazy data - fix: catch ApiNotFound exception when loading testcases - fix: print exception string with exception stage
This commit is contained in:
@@ -1,5 +1,23 @@
|
||||
# Release History
|
||||
|
||||
## 2.4.9 (2019-12-29)
|
||||
|
||||
**Added**
|
||||
|
||||
- test: add unittest for cli
|
||||
|
||||
**Changed**
|
||||
|
||||
- change: html report name defaults to be in UTC ISO 8601 format
|
||||
|
||||
**Fixed**
|
||||
|
||||
- fix: display validators in report when validate raised exception
|
||||
- fix: eval validator python script before validating
|
||||
- fix: do not strip string content when preparing lazy data
|
||||
- fix: catch ApiNotFound exception when loading testcases
|
||||
- fix: print exception string with exception stage
|
||||
|
||||
## 2.4.8 (2019-12-25)
|
||||
|
||||
**Added**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = "2.4.8"
|
||||
__version__ = "2.4.9"
|
||||
__description__ = "One-stop solution for HTTP(S) testing."
|
||||
|
||||
__all__ = ["__version__", "__description__"]
|
||||
|
||||
@@ -105,6 +105,7 @@ def main():
|
||||
err_code |= (0 if summary and summary["success"] else 1)
|
||||
except Exception as ex:
|
||||
color_print("!!!!!!!!!! exception stage: {} !!!!!!!!!!".format(runner.exception_stage), "YELLOW")
|
||||
color_print(str(ex), "RED")
|
||||
capture_exception(ex)
|
||||
err_code = 1
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ if is_py2:
|
||||
integer_types = (int, long)
|
||||
|
||||
FileNotFoundError = IOError
|
||||
import StringIO as io
|
||||
|
||||
elif is_py3:
|
||||
builtin_str = str
|
||||
@@ -57,3 +58,4 @@ elif is_py3:
|
||||
integer_types = (int,)
|
||||
|
||||
FileNotFoundError = FileNotFoundError
|
||||
import io as io
|
||||
|
||||
@@ -480,6 +480,8 @@ def load_cases(path, dot_env_path=None):
|
||||
loaded_content = None
|
||||
try:
|
||||
loaded_content = load_test_file(path)
|
||||
except exceptions.ApiNotFound as ex:
|
||||
logger.log_warning("Invalid api reference in {}: {}".format(path, ex))
|
||||
except exceptions.FileFormatError:
|
||||
logger.log_warning("Invalid test file format: {}".format(path))
|
||||
|
||||
|
||||
@@ -776,7 +776,6 @@ def prepare_lazy_data(content, functions_mapping=None, check_variables_set=None,
|
||||
|
||||
functions_mapping = functions_mapping or {}
|
||||
check_variables_set = check_variables_set or set()
|
||||
content = content.strip()
|
||||
content = LazyString(content, functions_mapping, check_variables_set, cached)
|
||||
|
||||
return content
|
||||
|
||||
@@ -33,15 +33,16 @@ def gen_html_report(summary, report_template=None, report_dir=None, report_file=
|
||||
|
||||
logger.log_info("Start to render Html report ...")
|
||||
|
||||
start_at_timestamp = int(summary["time"]["start_at"])
|
||||
summary["time"]["start_datetime"] = datetime.fromtimestamp(start_at_timestamp).strftime('%Y-%m-%d %H:%M:%S')
|
||||
start_at_timestamp = summary["time"]["start_at"]
|
||||
utc_time_iso_8601_str = datetime.utcfromtimestamp(start_at_timestamp).isoformat()
|
||||
summary["time"]["start_datetime"] = utc_time_iso_8601_str
|
||||
|
||||
if report_file:
|
||||
report_dir = os.path.dirname(report_file)
|
||||
report_file_name = os.path.basename(report_file)
|
||||
else:
|
||||
report_dir = report_dir or os.path.join(os.getcwd(), "reports")
|
||||
report_file_name = "{}.html".format(int(start_at_timestamp * 1000))
|
||||
report_file_name = "{}.html".format(utc_time_iso_8601_str)
|
||||
|
||||
if not os.path.isdir(report_dir):
|
||||
os.makedirs(report_dir)
|
||||
|
||||
@@ -303,8 +303,8 @@ class Runner(object):
|
||||
except exceptions.ValidationFailure:
|
||||
log_req_resp_details()
|
||||
raise
|
||||
|
||||
return validator.validation_results
|
||||
finally:
|
||||
self.validation_results = validator.validation_results
|
||||
|
||||
def _run_testcase(self, testcase_dict):
|
||||
""" run single testcase.
|
||||
@@ -382,9 +382,9 @@ class Runner(object):
|
||||
self._run_testcase(test_dict)
|
||||
else:
|
||||
# api
|
||||
validation_results = {}
|
||||
self.validation_results = {}
|
||||
try:
|
||||
validation_results = self._run_test(test_dict)
|
||||
self._run_test(test_dict)
|
||||
except Exception:
|
||||
# log exception request_type and name for locust stat
|
||||
self.exception_request_type = test_dict["request"]["method"]
|
||||
@@ -393,7 +393,7 @@ class Runner(object):
|
||||
finally:
|
||||
# get request/response data and validate results
|
||||
self.meta_datas = getattr(self.http_client_session, "meta_data", {})
|
||||
self.meta_datas["validators"] = validation_results
|
||||
self.meta_datas["validators"] = self.validation_results
|
||||
|
||||
def export_variables(self, output_variables_list):
|
||||
""" export current testcase variables
|
||||
|
||||
@@ -124,7 +124,8 @@ except Exception as ex:
|
||||
for validator in validators:
|
||||
|
||||
if isinstance(validator, dict) and validator.get("type") == "python_script":
|
||||
validator_dict, ex = self.validate_script(validator["script"])
|
||||
script = self.session_context.eval_content(validator["script"])
|
||||
validator_dict, ex = self.validate_script(script)
|
||||
if ex:
|
||||
validate_pass = False
|
||||
failures.append(ex)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "httprunner"
|
||||
version = "2.4.8"
|
||||
version = "2.4.9"
|
||||
description = "One-stop solution for HTTP(S) testing."
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
37
tests/test_cli.py
Normal file
37
tests/test_cli.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from httprunner.cli import main
|
||||
from httprunner.compat import io
|
||||
|
||||
|
||||
class TestCli(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.captured_output = io.StringIO()
|
||||
sys.stdout = self.captured_output
|
||||
|
||||
def tearDown(self):
|
||||
sys.stdout = sys.__stdout__ # Reset redirect.
|
||||
|
||||
def test_show_version(self):
|
||||
sys.argv = ["hrun", "-V"]
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
main()
|
||||
|
||||
self.assertEqual(cm.exception.code, 0)
|
||||
|
||||
from httprunner import __version__
|
||||
self.assertIn(__version__, self.captured_output.getvalue().strip())
|
||||
|
||||
def test_show_help(self):
|
||||
sys.argv = ["hrun", "-h"]
|
||||
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
main()
|
||||
|
||||
self.assertEqual(cm.exception.code, 0)
|
||||
|
||||
from httprunner import __description__
|
||||
self.assertIn(__description__, self.captured_output.getvalue().strip())
|
||||
Reference in New Issue
Block a user