diff --git a/httprunner/loader.py b/httprunner/loader.py index e18a72bb..4a2742ba 100644 --- a/httprunner/loader.py +++ b/httprunner/loader.py @@ -281,6 +281,7 @@ def load_debugtalk_functions(): project_mapping = {} tests_def_mapping = { + "PWD": None, "api": {}, "testcases": {} } @@ -323,6 +324,16 @@ def load_test(raw_testinfo): # reference api if "api" in raw_testinfo: api_name = raw_testinfo["api"] + + # api maybe defined in two types: + # 1, individual file: each file is corresponding to one api definition + # 2, api sets file: one file contains a list of api definitions + if not os.path.isabs(api_name): + api_path = os.path.join(tests_def_mapping["PWD"], api_name) + if os.path.isfile(api_path): + # type 1: api is defined in individual file + api_name = api_path + raw_testinfo["api_def"] = _get_api_definition(api_name) # TODO: reference proc functions @@ -495,22 +506,26 @@ def load_api_folder(api_folder_path): } """ - # TODO: refactor api storage format, use one file for each api. api_definition_mapping = {} api_items_mapping = load_folder_content(api_folder_path) for api_file_path, api_items in api_items_mapping.items(): # TODO: add JSON schema validation - for api_item in api_items: - key, api_dict = api_item.popitem() + if isinstance(api_items, list): + for api_item in api_items: + key, api_dict = api_item.popitem() + api_id = api_dict.get("id") + if api_id in api_definition_mapping: + logger.log_warning("API definition duplicated: {}".format(api_id)) - # TODO: replace id with api file path - api_id = api_dict.get("id") - if api_id in api_definition_mapping: - logger.log_warning("API definition duplicated: {}".format(api_id)) + api_definition_mapping[api_id] = api_dict - api_definition_mapping[api_id] = api_dict + elif isinstance(api_items, dict): + if api_file_path in api_definition_mapping: + logger.log_warning("API definition duplicated: {}".format(api_file_path)) + + api_definition_mapping[api_file_path] = api_items return api_definition_mapping @@ -579,6 +594,7 @@ def load_project_tests(test_path, dot_env_path=None): # load api tests_def_mapping["api"] = load_api_folder(os.path.join(project_working_directory, "api")) + tests_def_mapping["PWD"] = project_working_directory def load_tests(path, dot_env_path=None): diff --git a/tests/api/basic.yml b/tests/api/basic.yml index d879887c..4cab1b99 100644 --- a/tests/api/basic.yml +++ b/tests/api/basic.yml @@ -2,7 +2,6 @@ id: get_token name: get token variables: - user_agent: XXX device_sn: API_XXX os_platform: XXX diff --git a/tests/api/create_user.yml b/tests/api/create_user.yml new file mode 100644 index 00000000..2f7657b8 --- /dev/null +++ b/tests/api/create_user.yml @@ -0,0 +1,17 @@ +variables: + user_name: user0 + user_password: "000000" + uid: 9000 + token: XXX +request: + url: /api/users/$uid + method: POST + headers: + Content-Type: "application/json" + device_sn: $device_sn + token: $token + json: + name: $user_name + password: $user_password +validate: + - eq: ["status_code", 201] diff --git a/tests/api/delete_user.yml b/tests/api/delete_user.yml new file mode 100644 index 00000000..6fb8ac86 --- /dev/null +++ b/tests/api/delete_user.yml @@ -0,0 +1,12 @@ +variables: + uid: 9000 + token: XXX +request: + url: /api/users/$uid + method: DELETE + headers: + Content-Type: "application/json" + device_sn: $device_sn + token: $token +validate: + - eq: ["status_code", 200] \ No newline at end of file diff --git a/tests/api/get_headers.yml b/tests/api/get_headers.yml new file mode 100644 index 00000000..271a0cfe --- /dev/null +++ b/tests/api/get_headers.yml @@ -0,0 +1,16 @@ +variables: + n_secs: 1 +request: + url: /headers + headers: + Content-Type: "application/json" + device_sn: $device_sn + method: GET +setup_hooks: + - ${setup_hook_add_kwargs($request)} + - ${setup_hook_remove_kwargs($request)} +teardown_hooks: + - ${teardown_hook_sleep_N_secs($response, $n_secs)} +validate: + - eq: ["status_code", 200] + - contained_by: [content.headers.Host, "${get_httpbin_server()}"] diff --git a/tests/api/get_token.yml b/tests/api/get_token.yml new file mode 100644 index 00000000..9444fb9e --- /dev/null +++ b/tests/api/get_token.yml @@ -0,0 +1,22 @@ +name: get token +variables: + user_agent: XXX + device_sn: API_XXX + os_platform: XXX + app_version: XXX +request: + url: /api/get-token + method: POST + headers: + user_agent: $user_agent + device_sn: $device_sn + os_platform: $os_platform + app_version: $app_version + Content-Type: "application/json" + device_sn: $device_sn + json: + sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)} +validate: + - eq: ["status_code", 0] + - len_eq: ["content.token", 12] + - contains: [{"a": 1, "b": 2}, "a"] diff --git a/tests/api/get_user.yml b/tests/api/get_user.yml new file mode 100644 index 00000000..3f1ad96a --- /dev/null +++ b/tests/api/get_user.yml @@ -0,0 +1,12 @@ +variables: + uid: 9000 + token: XXX +request: + url: /api/users/$uid + method: GET + headers: + Content-Type: "application/json" + device_sn: $device_sn + token: $token +validate: + - eq: ["status_code", 200] \ No newline at end of file diff --git a/tests/api/get_users.yml b/tests/api/get_users.yml new file mode 100644 index 00000000..37285bff --- /dev/null +++ b/tests/api/get_users.yml @@ -0,0 +1,11 @@ +variables: + token: XXX +request: + url: /api/users + method: GET + headers: + Content-Type: "application/json" + device_sn: $device_sn + token: $token +validate: + - eq: ["status_code", 200] \ No newline at end of file diff --git a/tests/api/reset_all.yml b/tests/api/reset_all.yml new file mode 100644 index 00000000..ca357975 --- /dev/null +++ b/tests/api/reset_all.yml @@ -0,0 +1,12 @@ +variables: + token: XXX +request: + url: /api/reset-all + method: GET + headers: + Content-Type: "application/json" + device_sn: $device_sn + token: $token +validate: + - eq: ["status_code", 200] + - eq: ["content.success", true] \ No newline at end of file diff --git a/tests/api/update_user.yml b/tests/api/update_user.yml new file mode 100644 index 00000000..9069f0de --- /dev/null +++ b/tests/api/update_user.yml @@ -0,0 +1,17 @@ +variables: + user_name: user0 + user_password: "000000" + uid: 9000 + token: XXX +request: + url: /api/users/$uid + method: PUT + headers: + Content-Type: "application/json" + device_sn: $device_sn + token: $token + json: + name: $user_name + password: $user_password +validate: + - eq: ["status_code", 200] \ No newline at end of file diff --git a/tests/test_loader.py b/tests/test_loader.py index 3e2b66b6..fa7be975 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -439,6 +439,8 @@ class TestSuiteLoader(unittest.TestCase): api_definition_mapping = loader.load_api_folder(path) self.assertIn("get_token", api_definition_mapping) self.assertIn("request", api_definition_mapping["get_token"]) + api_path = os.path.join(os.getcwd(), "tests", "api", "get_token.yml") + self.assertIn(api_path, api_definition_mapping) def test_load_project_tests(self): loader.load_project_tests(os.path.join(os.getcwd(), "tests")) diff --git a/tests/testcases/create_and_check.yml b/tests/testcases/create_and_check.yml index 5a3c22a8..146a0f44 100644 --- a/tests/testcases/create_and_check.yml +++ b/tests/testcases/create_and_check.yml @@ -15,7 +15,7 @@ - test: name: make sure user $uid does not exist - api: get_user + api: api/get_user.yml variables: uid: $uid token: $token @@ -25,7 +25,7 @@ - test: name: create user $uid - api: create_user + api: api/create_user.yml variables: user_name: "user1" user_password: "123456" @@ -37,7 +37,7 @@ - test: name: check if user $uid exists - api: get_user + api: api/get_user.yml variables: uid: $uid token: $token diff --git a/tests/testcases/setup.yml b/tests/testcases/setup.yml index cdb57455..24414d9f 100644 --- a/tests/testcases/setup.yml +++ b/tests/testcases/setup.yml @@ -13,7 +13,7 @@ - test: name: get token (setup) - api: get_token + api: api/get_token.yml variables: user_agent: 'iOS/10.3' device_sn: $device_sn @@ -27,6 +27,6 @@ - test: name: reset all users - api: reset_all + api: api/reset_all.yml variables: token: $token