From 32493947326b5af9db249a2d0219fee2ce71c842 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Fri, 14 Dec 2018 17:53:17 +0800 Subject: [PATCH] add new feature: parameters --- httprunner/parser.py | 29 ++++-- httprunner/utils.py | 6 +- tests/test_api.py | 92 +++++++------------ tests/testcases/create_and_check.yml | 4 +- .../create_users_with_parameters.yml | 16 ++++ 5 files changed, 79 insertions(+), 68 deletions(-) create mode 100644 tests/testsuites/create_users_with_parameters.yml diff --git a/httprunner/parser.py b/httprunner/parser.py index f679364e..f9dd84d0 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -841,7 +841,7 @@ def __get_parsed_testsuite_testcases(testcases, testsuite_config, project_mappin """ override testscases with testsuite config variables, base_url and verify. variables priority: - testsuite config > testcase config > testcase_def config > testcase_def tests > api + parameters > testsuite config > testcase config > testcase_def config > testcase_def tests > api Args: testcases (dict): @@ -883,9 +883,6 @@ def __get_parsed_testsuite_testcases(testcases, testsuite_config, project_mappin for testcase_name, testcase in testcases.items(): - # TODO: add parameterize - # parameters = testcase.get("parameters") - parsed_testcase = testcase.pop("testcase_def") parsed_testcase.setdefault("config", {}) parsed_testcase["path"] = testcase["testcase"] @@ -921,8 +918,28 @@ def __get_parsed_testsuite_testcases(testcases, testsuite_config, project_mappin if parsed_config_variables: parsed_testcase["config"]["variables"] = parsed_config_variables - _parse_testcase(parsed_testcase, project_mapping) - parsed_testcase_list.append(parsed_testcase) + # parse parameters + if "parameters" in testcase: + cartesian_product_parameters = parse_parameters( + testcase["parameters"], + parsed_config_variables, + functions + ) + + for parameter_variables in cartesian_product_parameters: + # deepcopy to avoid influence between parameters + parsed_testcase_copied = utils.deepcopy_dict(parsed_testcase) + parsed_config_variables_copied = utils.deepcopy_dict(parsed_config_variables) + parsed_testcase_copied["config"]["variables"] = utils.extend_variables( + parsed_config_variables_copied, + parameter_variables + ) + _parse_testcase(parsed_testcase_copied, project_mapping) + parsed_testcase_list.append(parsed_testcase_copied) + + else: + _parse_testcase(parsed_testcase, project_mapping) + parsed_testcase_list.append(parsed_testcase) return parsed_testcase_list diff --git a/httprunner/utils.py b/httprunner/utils.py index ae62eac8..9dd39618 100644 --- a/httprunner/utils.py +++ b/httprunner/utils.py @@ -310,11 +310,11 @@ def ensure_mapping_format(variables): """ if isinstance(variables, list): - variables_ordered_dict = {} + variables_dict = {} for map_dict in variables: - variables_ordered_dict.update(map_dict) + variables_dict.update(map_dict) - return variables_ordered_dict + return variables_dict elif isinstance(variables, dict): return variables diff --git a/tests/test_api.py b/tests/test_api.py index d490c818..38dce8d4 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -334,61 +334,36 @@ class TestHttpRunner(ApiServerUnittest): def test_run_testcase_with_parameters(self): testcase_file_path = os.path.join( - os.getcwd(), 'tests/data/demo_parameters.yml') + os.getcwd(), 'tests/testsuites/create_users_with_parameters.yml') self.runner.run(testcase_file_path) summary = self.runner.summary - # TODO: add parameterize - # self.assertEqual( - # summary["details"][0]["in_out"]["in"]["user_agent"], - # "iOS/10.1" - # ) - # self.assertEqual( - # summary["details"][2]["in_out"]["in"]["user_agent"], - # "iOS/10.2" - # ) - # self.assertEqual( - # summary["details"][4]["in_out"]["in"]["user_agent"], - # "iOS/10.3" - # ) self.assertTrue(summary["success"]) - self.assertEqual(len(summary["details"]), 1) - # self.assertEqual(len(summary["details"]), 3 * 2) - # self.assertEqual(summary["stat"]["testsRun"], 3 * 2) - self.assertIn("in", summary["details"][0]["in_out"]) - self.assertIn("out", summary["details"][0]["in_out"]) - - def test_run_testcase_with_parameters_name(self): - testcase_file_path = os.path.join( - os.getcwd(), 'tests/data/demo_parameters.yml') - tests_mapping = loader.load_tests(testcase_file_path) - parsed_tests_mapping = parser.parse_tests(tests_mapping) - test_suite = self.runner._add_tests(parsed_tests_mapping) - + self.assertEqual(len(summary["details"]), 3 * 2) + self.assertEqual(summary["stat"]["testsRun"], 3 * 2 * 4) self.assertEqual( - test_suite._tests[0].teststeps[0]['name'], - 'get token with iOS/10.1 and test1' + summary["details"][0]["name"], + "create user 101 and check result for TESTSUITE_X1." + ) + self.assertEqual( + summary["details"][5]["name"], + "create user 103 and check result for TESTSUITE_X2." + ) + self.assertEqual( + summary["details"][0]["stat"]["testsRun"], + 4 + ) + self.assertEqual( + summary["details"][0]["records"][2]["name"], + "create user 101 for TESTSUITE_X1" + ) + self.assertEqual( + summary["details"][3]["records"][2]["name"], + "create user 102 for TESTSUITE_X2" + ) + self.assertEqual( + summary["details"][5]["records"][2]["name"], + "create user 103 for TESTSUITE_X2" ) - # TODO: add parameterize - # self.assertEqual( - # test_suite._tests[1].tests[0]['name'], - # 'get token with iOS/10.1 and test2' - # ) - # self.assertEqual( - # test_suite._tests[2].tests[0]['name'], - # 'get token with iOS/10.2 and test1' - # ) - # self.assertEqual( - # test_suite._tests[3].tests[0]['name'], - # 'get token with iOS/10.2 and test2' - # ) - # self.assertEqual( - # test_suite._tests[4].tests[0]['name'], - # 'get token with iOS/10.3 and test1' - # ) - # self.assertEqual( - # test_suite._tests[5].tests[0]['name'], - # 'get token with iOS/10.3 and test2' - # ) # def test_validate_response_content(self): # # TODO: fix compatibility with Python 2.7 @@ -478,7 +453,7 @@ class TestApi(ApiServerUnittest): results = tests_results[0][1] self.assertEqual( results.records[0]["name"], - "setup and reset all (override)." + "setup and reset all (override) for TESTCASE_CREATE_XXX." ) self.assertEqual( results.records[1]["name"], @@ -512,7 +487,10 @@ class TestApi(ApiServerUnittest): self.assertIsInstance(testcase_tests["testcase_def"], dict) self.assertEqual(testcase_tests["testcase_def"]["config"]["name"], "create user and check result.") self.assertEqual(len(testcase_tests["testcase_def"]["teststeps"]), 4) - self.assertEqual(testcase_tests["testcase_def"]["teststeps"][0]["name"], "setup and reset all (override).") + self.assertEqual( + testcase_tests["testcase_def"]["teststeps"][0]["name"], + "setup and reset all (override) for $device_sn." + ) def test_testsuite_parser(self): testcase_path = "tests/testsuites/create_users.yml" @@ -525,7 +503,7 @@ class TestApi(ApiServerUnittest): self.assertEqual(len(parsed_testcases[0]["teststeps"]), 4) testcase1 = parsed_testcases[0]["teststeps"][0] - self.assertEqual(testcase1["config"]["name"], "setup and reset all (override).") + self.assertIn("setup and reset all (override)", testcase1["config"]["name"]) self.assertNotIn("testcase_def", testcase1) self.assertEqual(len(testcase1["teststeps"]), 2) self.assertEqual( @@ -544,7 +522,7 @@ class TestApi(ApiServerUnittest): self.assertEqual(len(test_suite._tests), 2) tests = test_suite._tests[0].teststeps - self.assertEqual(tests[0]["config"]["name"], "setup and reset all (override).") + self.assertIn("setup and reset all (override)", tests[0]["config"]["name"]) def test_testsuite_run_suite(self): testcase_path = "tests/testsuites/create_users.yml" @@ -559,9 +537,9 @@ class TestApi(ApiServerUnittest): self.assertEqual(len(tests_results[0][1].records), 4) results = tests_results[0][1] - self.assertEqual( - results.records[0]["name"], - "setup and reset all (override)." + self.assertIn( + "setup and reset all (override)", + results.records[0]["name"] ) self.assertIn( results.records[1]["name"], diff --git a/tests/testcases/create_and_check.yml b/tests/testcases/create_and_check.yml index 146a0f44..8e3ddb88 100644 --- a/tests/testcases/create_and_check.yml +++ b/tests/testcases/create_and_check.yml @@ -8,7 +8,7 @@ base_url: "http://127.0.0.1:5000" - test: - name: setup and reset all (override). + name: setup and reset all (override) for $device_sn. testcase: testcases/setup.yml output: - token @@ -24,7 +24,7 @@ - eq: ["content.success", false] - test: - name: create user $uid + name: create user $uid for $device_sn api: api/create_user.yml variables: user_name: "user1" diff --git a/tests/testsuites/create_users_with_parameters.yml b/tests/testsuites/create_users_with_parameters.yml new file mode 100644 index 00000000..7374f409 --- /dev/null +++ b/tests/testsuites/create_users_with_parameters.yml @@ -0,0 +1,16 @@ +config: + name: create users with uid + variables: + device_sn: ${gen_random_string(15)} + base_url: "http://127.0.0.1:5000" + +testcases: + create user $uid and check result for $device_sn.: + testcase: testcases/create_and_check.yml + weight: 2 + variables: + uid: 1000 + device_sn: TESTSUITE_XXX + parameters: + uid: [101, 102, 103] + device_sn: [TESTSUITE_X1, TESTSUITE_X2]