From 7d9ffb097f57407d5e0c8a09917958b9ad0bcfde Mon Sep 17 00:00:00 2001 From: debugtalk Date: Thu, 22 Nov 2018 21:48:03 +0800 Subject: [PATCH] Save loaded tests and parsed tests to JSON file. --- httprunner/api.py | 48 +++++++++++++++++++++------------------------ httprunner/cli.py | 9 ++++++++- httprunner/utils.py | 27 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/httprunner/api.py b/httprunner/api.py index 97ebde3b..a00ab166 100644 --- a/httprunner/api.py +++ b/httprunner/api.py @@ -134,37 +134,14 @@ class HttpRunner(object): self.summary["details"].append(testcase_summary) - def _run_tests(self, tests_mapping): - """ start to run test with variables mapping. - - Args: - tests_mapping (dict): list of testcase_dict, each testcase is corresponding to a YAML/JSON file - - Returns: - instance: HttpRunner() instance - - """ - self.exception_stage = "parse tests" - parser.parse_tests(tests_mapping) - - self.exception_stage = "add tests to test suite" - test_suite = self._add_tests(tests_mapping) - - self.exception_stage = "run test suite" - results = self._run_suite(test_suite) - - self.exception_stage = "aggregate results" - self._aggregate(results) - - return self - - def run(self, path_or_testcases, dot_env_path=None, mapping=None): + def run(self, path_or_testcases, dot_env_path=None, mapping=None, save_tests=False): """ main interface, run testcases with variables mapping. Args: path_or_testcases (str/list/dict): testcase file/foler path, or valid testcases. dot_env_path (str): specified .env file path. mapping (dict): if mapping is specified, it will override variables in config block. + save_tests (bool): set if save loaded/parsed tests to JSON file. Returns: instance: HttpRunner() instance @@ -177,10 +154,29 @@ class HttpRunner(object): elif validator.is_testcase_path(path_or_testcases): tests_mapping = loader.load_tests(path_or_testcases, dot_env_path) tests_mapping["project_mapping"]["variables"] = mapping or {} + tests_mapping["project_mapping"]["test_path"] = path_or_testcases else: raise exceptions.ParamsError("invalid testcase path or testcases.") - return self._run_tests(tests_mapping) + if save_tests: + utils.dump_tests(tests_mapping, "loaded") + + self.exception_stage = "parse tests" + parser.parse_tests(tests_mapping) + + if save_tests: + utils.dump_tests(tests_mapping, "parsed") + + self.exception_stage = "add tests to test suite" + test_suite = self._add_tests(tests_mapping) + + self.exception_stage = "run test suite" + results = self._run_suite(test_suite) + + self.exception_stage = "aggregate results" + self._aggregate(results) + + return self def gen_html_report(self, html_report_name=None, html_report_template=None): """ generate html report and return report path. diff --git a/httprunner/cli.py b/httprunner/cli.py index d242d456..7c928535 100644 --- a/httprunner/cli.py +++ b/httprunner/cli.py @@ -45,6 +45,9 @@ def main_hrun(): parser.add_argument( '--failfast', action='store_true', default=False, help="Stop the test run on the first error or failure.") + parser.add_argument( + '--save-tests', action='store_true', default=False, + help="Save loaded tests and parsed tests to JSON file.") parser.add_argument( '--startproject', help="Specify new project name.") @@ -80,7 +83,11 @@ def main_hrun(): for path in args.testcase_paths: try: runner = HttpRunner(failfast=args.failfast) - runner.run(path, dot_env_path=args.dot_env_path) + runner.run( + path, + dot_env_path=args.dot_env_path, + save_tests=args.save_tests + ) except Exception: logger.log_error("!!!!!!!!!! exception stage: {} !!!!!!!!!!".format(runner.exception_stage)) raise diff --git a/httprunner/utils.py b/httprunner/utils.py index 069b6272..9b381fa2 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -583,6 +583,33 @@ def prettify_json_file(file_list): print("success: {}".format(outfile)) +def dump_tests(tests_mapping, tag_name): + """ dump all tests data (except functions) to json file. + + Args: + tests_mapping (dict): data to dump + tag_name (str): tag name, loaded/parsed + + """ + project_mapping = tests_mapping.get("project_mapping", {}) + test_path = project_mapping.get("test_path") or "tests_mapping" + dir_path = project_mapping.get("PWD") or os.getcwd() + file_name, file_suffix = os.path.splitext(os.path.basename(test_path)) + dump_file_path = os.path.join(dir_path, "{}.{}.json".format(file_name, tag_name)) + + tests_to_dump = { + "project_mapping": { + key: project_mapping[key] for key in project_mapping if key != "functions" + }, + "testcases": tests_mapping["testcases"] + } + with open(dump_file_path, 'w', encoding='utf-8') as outfile: + json.dump(tests_to_dump, outfile, indent=4, separators=(',', ': ')) + + msg = "{} file generated successfully: {}".format(tag_name, dump_file_path) + logger.color_print(msg, "BLUE") + + def get_python2_retire_msg(): retire_day = datetime(2020, 1, 1) today = datetime.now()