mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-30 03:51:27 +08:00
refactor: make loader as submodule, split to check/locate/load/cases
This commit is contained in:
241
httprunner/loader/load.py
Normal file
241
httprunner/loader/load.py
Normal file
@@ -0,0 +1,241 @@
|
||||
import csv
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
|
||||
import yaml
|
||||
|
||||
from httprunner import built_in
|
||||
from httprunner import exceptions, logger, utils
|
||||
from httprunner.loader.check import check_testcase_format, is_function
|
||||
from httprunner.loader.locate import get_project_working_directory
|
||||
|
||||
try:
|
||||
# PyYAML version >= 5.1
|
||||
# ref: https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation
|
||||
yaml.warnings({'YAMLLoadWarning': False})
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
def _load_yaml_file(yaml_file):
|
||||
""" load yaml file and check file content format
|
||||
"""
|
||||
with io.open(yaml_file, 'r', encoding='utf-8') as stream:
|
||||
yaml_content = yaml.load(stream)
|
||||
check_testcase_format(yaml_file, yaml_content)
|
||||
return yaml_content
|
||||
|
||||
|
||||
def _load_json_file(json_file):
|
||||
""" load json file and check file content format
|
||||
"""
|
||||
with io.open(json_file, encoding='utf-8') as data_file:
|
||||
try:
|
||||
json_content = json.load(data_file)
|
||||
except exceptions.JSONDecodeError:
|
||||
err_msg = u"JSONDecodeError: JSON file format error: {}".format(json_file)
|
||||
logger.log_error(err_msg)
|
||||
raise exceptions.FileFormatError(err_msg)
|
||||
|
||||
check_testcase_format(json_file, json_content)
|
||||
return json_content
|
||||
|
||||
|
||||
def load_csv_file(csv_file):
|
||||
""" load csv file and check file content format
|
||||
|
||||
Args:
|
||||
csv_file (str): csv file path, csv file content is like below:
|
||||
|
||||
Returns:
|
||||
list: list of parameters, each parameter is in dict format
|
||||
|
||||
Examples:
|
||||
>>> cat csv_file
|
||||
username,password
|
||||
test1,111111
|
||||
test2,222222
|
||||
test3,333333
|
||||
|
||||
>>> load_csv_file(csv_file)
|
||||
[
|
||||
{'username': 'test1', 'password': '111111'},
|
||||
{'username': 'test2', 'password': '222222'},
|
||||
{'username': 'test3', 'password': '333333'}
|
||||
]
|
||||
|
||||
"""
|
||||
if not os.path.isabs(csv_file):
|
||||
pwd = get_project_working_directory()
|
||||
# make compatible with Windows/Linux
|
||||
csv_file = os.path.join(pwd, *csv_file.split("/"))
|
||||
|
||||
if not os.path.isfile(csv_file):
|
||||
# file path not exist
|
||||
raise exceptions.CSVNotFound(csv_file)
|
||||
|
||||
csv_content_list = []
|
||||
|
||||
with io.open(csv_file, encoding='utf-8') as csvfile:
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
csv_content_list.append(row)
|
||||
|
||||
return csv_content_list
|
||||
|
||||
|
||||
def load_file(file_path):
|
||||
if not os.path.isfile(file_path):
|
||||
raise exceptions.FileNotFound("{} does not exist.".format(file_path))
|
||||
|
||||
file_suffix = os.path.splitext(file_path)[1].lower()
|
||||
if file_suffix == '.json':
|
||||
return _load_json_file(file_path)
|
||||
elif file_suffix in ['.yaml', '.yml']:
|
||||
return _load_yaml_file(file_path)
|
||||
elif file_suffix == ".csv":
|
||||
return load_csv_file(file_path)
|
||||
else:
|
||||
# '' or other suffix
|
||||
err_msg = u"Unsupported file format: {}".format(file_path)
|
||||
logger.log_warning(err_msg)
|
||||
return []
|
||||
|
||||
|
||||
def load_folder_files(folder_path, recursive=True):
|
||||
""" load folder path, return all files endswith yml/yaml/json in list.
|
||||
|
||||
Args:
|
||||
folder_path (str): specified folder path to load
|
||||
recursive (bool): load files recursively if True
|
||||
|
||||
Returns:
|
||||
list: files endswith yml/yaml/json
|
||||
"""
|
||||
if isinstance(folder_path, (list, set)):
|
||||
files = []
|
||||
for path in set(folder_path):
|
||||
files.extend(load_folder_files(path, recursive))
|
||||
|
||||
return files
|
||||
|
||||
if not os.path.exists(folder_path):
|
||||
return []
|
||||
|
||||
file_list = []
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(folder_path):
|
||||
filenames_list = []
|
||||
|
||||
for filename in filenames:
|
||||
if not filename.endswith(('.yml', '.yaml', '.json')):
|
||||
continue
|
||||
|
||||
filenames_list.append(filename)
|
||||
|
||||
for filename in filenames_list:
|
||||
file_path = os.path.join(dirpath, filename)
|
||||
file_list.append(file_path)
|
||||
|
||||
if not recursive:
|
||||
break
|
||||
|
||||
return file_list
|
||||
|
||||
|
||||
def load_dot_env_file(dot_env_path):
|
||||
""" load .env file.
|
||||
|
||||
Args:
|
||||
dot_env_path (str): .env file path
|
||||
|
||||
Returns:
|
||||
dict: environment variables mapping
|
||||
|
||||
{
|
||||
"UserName": "debugtalk",
|
||||
"Password": "123456",
|
||||
"PROJECT_KEY": "ABCDEFGH"
|
||||
}
|
||||
|
||||
Raises:
|
||||
exceptions.FileFormatError: If .env file format is invalid.
|
||||
|
||||
"""
|
||||
if not os.path.isfile(dot_env_path):
|
||||
return {}
|
||||
|
||||
logger.log_info("Loading environment variables from {}".format(dot_env_path))
|
||||
env_variables_mapping = {}
|
||||
|
||||
with io.open(dot_env_path, 'r', encoding='utf-8') as fp:
|
||||
for line in fp:
|
||||
# maxsplit=1
|
||||
if "=" in line:
|
||||
variable, value = line.split("=", 1)
|
||||
elif ":" in line:
|
||||
variable, value = line.split(":", 1)
|
||||
else:
|
||||
raise exceptions.FileFormatError(".env format error")
|
||||
|
||||
env_variables_mapping[variable.strip()] = value.strip()
|
||||
|
||||
utils.set_os_environ(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):
|
||||
""" load python module functions.
|
||||
|
||||
Args:
|
||||
module: python module
|
||||
|
||||
Returns:
|
||||
dict: functions mapping for specified python module
|
||||
|
||||
{
|
||||
"func1_name": func1,
|
||||
"func2_name": func2
|
||||
}
|
||||
|
||||
"""
|
||||
module_functions = {}
|
||||
|
||||
for name, item in vars(module).items():
|
||||
if is_function(item):
|
||||
module_functions[name] = item
|
||||
|
||||
return module_functions
|
||||
|
||||
|
||||
def load_builtin_functions():
|
||||
""" load built_in module functions
|
||||
"""
|
||||
return load_module_functions(built_in)
|
||||
|
||||
Reference in New Issue
Block a user