mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-01 22:09:35 +08:00
feat: load api content on demand
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
# Release History
|
# Release History
|
||||||
|
|
||||||
## 2.4.3 (2019-12-13)
|
## 2.4.3 (2019-12-16)
|
||||||
|
|
||||||
|
**Added**
|
||||||
|
|
||||||
|
- feat: load api content on demand
|
||||||
|
|
||||||
**Changed**
|
**Changed**
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import importlib
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from httprunner import exceptions, logger, utils
|
from httprunner import exceptions, logger, utils
|
||||||
from httprunner.loader.load import load_module_functions, load_folder_content, load_file, load_dot_env_file, \
|
from httprunner.loader.load import load_module_functions, load_file, load_dot_env_file, \
|
||||||
load_folder_files
|
load_folder_files
|
||||||
from httprunner.loader.locate import init_project_working_directory, get_project_working_directory
|
from httprunner.loader.locate import init_project_working_directory, get_project_working_directory
|
||||||
|
|
||||||
@@ -49,12 +49,16 @@ def __extend_with_api_ref(raw_testinfo):
|
|||||||
# type 1: api is defined in individual file
|
# type 1: api is defined in individual file
|
||||||
api_name = api_path
|
api_name = api_path
|
||||||
|
|
||||||
try:
|
if api_name in tests_def_mapping["api"]:
|
||||||
block = tests_def_mapping["api"][api_name]
|
block = tests_def_mapping["api"][api_name]
|
||||||
# NOTICE: avoid project_mapping been changed during iteration.
|
elif not os.path.isfile(api_name):
|
||||||
raw_testinfo["api_def"] = utils.deepcopy_dict(block)
|
|
||||||
except KeyError:
|
|
||||||
raise exceptions.ApiNotFound("{} not found!".format(api_name))
|
raise exceptions.ApiNotFound("{} not found!".format(api_name))
|
||||||
|
else:
|
||||||
|
block = load_file(api_name)
|
||||||
|
|
||||||
|
# NOTICE: avoid project_mapping been changed during iteration.
|
||||||
|
raw_testinfo["api_def"] = utils.deepcopy_dict(block)
|
||||||
|
tests_def_mapping["api"][api_name] = block
|
||||||
|
|
||||||
|
|
||||||
def __extend_with_testcase_ref(raw_testinfo):
|
def __extend_with_testcase_ref(raw_testinfo):
|
||||||
@@ -376,77 +380,6 @@ def load_test_file(path):
|
|||||||
return loaded_content
|
return loaded_content
|
||||||
|
|
||||||
|
|
||||||
def load_api_folder(api_folder_path):
|
|
||||||
""" load api definitions from api folder.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
api_folder_path (str): api files folder.
|
|
||||||
|
|
||||||
api file should be in the following format:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"api": {
|
|
||||||
"def": "api_login",
|
|
||||||
"request": {},
|
|
||||||
"validate": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"api": {
|
|
||||||
"def": "api_logout",
|
|
||||||
"request": {},
|
|
||||||
"validate": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: api definition mapping.
|
|
||||||
|
|
||||||
{
|
|
||||||
"api_login": {
|
|
||||||
"function_meta": {"func_name": "api_login", "args": [], "kwargs": {}}
|
|
||||||
"request": {}
|
|
||||||
},
|
|
||||||
"api_logout": {
|
|
||||||
"function_meta": {"func_name": "api_logout", "args": [], "kwargs": {}}
|
|
||||||
"request": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
if isinstance(api_items, list):
|
|
||||||
for api_item in api_items:
|
|
||||||
key, api_dict = api_item.popitem()
|
|
||||||
api_id = api_dict.get("id") or api_dict.get("def") \
|
|
||||||
or api_dict.get("name")
|
|
||||||
if key != "api" or not api_id:
|
|
||||||
raise exceptions.ParamsError(
|
|
||||||
"Invalid API defined in {}".format(api_file_path))
|
|
||||||
|
|
||||||
if api_id in api_definition_mapping:
|
|
||||||
raise exceptions.ParamsError(
|
|
||||||
"Duplicated API ({}) defined in {}".format(
|
|
||||||
api_id, api_file_path))
|
|
||||||
else:
|
|
||||||
api_definition_mapping[api_id] = api_dict
|
|
||||||
|
|
||||||
elif isinstance(api_items, dict):
|
|
||||||
if api_file_path in api_definition_mapping:
|
|
||||||
raise exceptions.ParamsError(
|
|
||||||
"Duplicated API defined: {}".format(api_file_path))
|
|
||||||
else:
|
|
||||||
api_definition_mapping[api_file_path] = api_items
|
|
||||||
|
|
||||||
return api_definition_mapping
|
|
||||||
|
|
||||||
|
|
||||||
def load_project_data(test_path, dot_env_path=None):
|
def load_project_data(test_path, dot_env_path=None):
|
||||||
""" load api, testcases, .env, debugtalk.py functions.
|
""" load api, testcases, .env, debugtalk.py functions.
|
||||||
api/testcases folder is relative to project_working_directory
|
api/testcases folder is relative to project_working_directory
|
||||||
@@ -482,9 +415,6 @@ def load_project_data(test_path, dot_env_path=None):
|
|||||||
project_mapping["functions"] = debugtalk_functions
|
project_mapping["functions"] = debugtalk_functions
|
||||||
project_mapping["test_path"] = os.path.abspath(test_path)
|
project_mapping["test_path"] = os.path.abspath(test_path)
|
||||||
|
|
||||||
# load api
|
|
||||||
tests_def_mapping["api"] = load_api_folder(os.path.join(project_working_directory, "api"))
|
|
||||||
|
|
||||||
return project_mapping
|
return project_mapping
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -185,31 +185,6 @@ def load_dot_env_file(dot_env_path):
|
|||||||
return env_variables_mapping
|
return env_variables_mapping
|
||||||
|
|
||||||
|
|
||||||
def load_folder_content(folder_path):
|
|
||||||
""" load api/testcases/testsuites definitions from folder.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
folder_path (str): api/testcases/testsuites files folder.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: api definition mapping.
|
|
||||||
|
|
||||||
{
|
|
||||||
"tests/api/basic.yml": [
|
|
||||||
{"api": {"def": "api_login", "request": {}, "validate": []}},
|
|
||||||
{"api": {"def": "api_logout", "request": {}, "validate": []}}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
items_mapping = {}
|
|
||||||
|
|
||||||
for file_path in load_folder_files(folder_path):
|
|
||||||
items_mapping[file_path] = load_file(file_path)
|
|
||||||
|
|
||||||
return items_mapping
|
|
||||||
|
|
||||||
|
|
||||||
def load_module_functions(module):
|
def load_module_functions(module):
|
||||||
""" load python module functions.
|
""" load python module functions.
|
||||||
|
|
||||||
|
|||||||
@@ -277,13 +277,6 @@ class TestSuiteLoader(unittest.TestCase):
|
|||||||
with self.assertRaises(exceptions.FileNotFound):
|
with self.assertRaises(exceptions.FileNotFound):
|
||||||
loader.load_cases(path)
|
loader.load_cases(path)
|
||||||
|
|
||||||
def test_load_api_folder(self):
|
|
||||||
path = os.path.join(os.getcwd(), "tests", "api")
|
|
||||||
api_definition_mapping = buildup.load_api_folder(path)
|
|
||||||
api_file_path = os.path.join(os.getcwd(), "tests", "api", "get_token.yml")
|
|
||||||
self.assertIn(api_file_path, api_definition_mapping)
|
|
||||||
self.assertIn("request", api_definition_mapping[api_file_path])
|
|
||||||
|
|
||||||
def test_load_project_tests(self):
|
def test_load_project_tests(self):
|
||||||
buildup.load_project_data(os.path.join(os.getcwd(), "tests"))
|
buildup.load_project_data(os.path.join(os.getcwd(), "tests"))
|
||||||
api_file_path = os.path.join(os.getcwd(), "tests", "api", "get_token.yml")
|
api_file_path = os.path.join(os.getcwd(), "tests", "api", "get_token.yml")
|
||||||
|
|||||||
@@ -150,10 +150,3 @@ class TestFileLoader(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
env_variables_mapping = load.load_dot_env_file(dot_env_path)
|
env_variables_mapping = load.load_dot_env_file(dot_env_path)
|
||||||
self.assertEqual(env_variables_mapping, {})
|
self.assertEqual(env_variables_mapping, {})
|
||||||
|
|
||||||
def test_load_folder_content(self):
|
|
||||||
path = os.path.join(os.getcwd(), "tests", "api")
|
|
||||||
items_mapping = load.load_folder_content(path)
|
|
||||||
file_path = os.path.join(os.getcwd(), "tests", "api", "reset_all.yml")
|
|
||||||
self.assertIn(file_path, items_mapping)
|
|
||||||
self.assertIsInstance(items_mapping[file_path], dict)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user