mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-13 08:19:44 +08:00
129 lines
3.7 KiB
Python
129 lines
3.7 KiB
Python
import os
|
|
import subprocess
|
|
from typing import Union, Text, List
|
|
|
|
import jinja2
|
|
from loguru import logger
|
|
|
|
from httprunner import exceptions
|
|
from httprunner.exceptions import TestCaseFormatError
|
|
from httprunner.loader import load_testcase_file, load_folder_files
|
|
|
|
__TMPL__ = """# NOTICE: Generated By HttpRunner. DO'NOT EDIT!
|
|
from httprunner import HttpRunner, TConfig, TStep, TestCase
|
|
|
|
|
|
class {{ class_name }}(TestCase):
|
|
config = TConfig(**{{ config }})
|
|
|
|
teststeps = [
|
|
{% for teststep in teststeps %}
|
|
TStep(**{{ teststep }}),
|
|
{% endfor %}
|
|
]
|
|
|
|
def test_start(self):
|
|
HttpRunner(self.config, self.teststeps).run()
|
|
|
|
"""
|
|
|
|
|
|
def make_testcase(testcase_path: str) -> Union[str, None]:
|
|
logger.info(f"start to make testcase: {testcase_path}")
|
|
try:
|
|
testcase, _ = load_testcase_file(testcase_path)
|
|
except TestCaseFormatError:
|
|
return None
|
|
|
|
template = jinja2.Template(__TMPL__)
|
|
|
|
raw_file_name, _ = os.path.splitext(os.path.basename(testcase_path))
|
|
# convert title case, e.g. request_with_variables => RequestWithVariables
|
|
name_in_title_case = raw_file_name.title().replace("_", "")
|
|
|
|
testcase_dir = os.path.dirname(testcase_path)
|
|
testcase_python_path = os.path.join(testcase_dir, f"{raw_file_name}_test.py")
|
|
|
|
config = testcase["config"]
|
|
config["path"] = testcase_python_path
|
|
data = {
|
|
"class_name": f"TestCase{name_in_title_case}",
|
|
"config": config,
|
|
"teststeps": testcase["teststeps"],
|
|
}
|
|
content = template.render(data)
|
|
|
|
with open(testcase_python_path, "w") as f:
|
|
f.write(content)
|
|
|
|
logger.info(f"generated testcase: {testcase_python_path}")
|
|
return testcase_python_path
|
|
|
|
|
|
def convert_testcase_path(testcase_path: Text) -> Text:
|
|
"""convert single YAML/JSON testcase path to python file"""
|
|
if os.path.isdir(testcase_path):
|
|
# folder does not need to convert
|
|
return testcase_path
|
|
|
|
file_suffix = os.path.splitext(testcase_path)[1].lower()
|
|
if file_suffix == ".json":
|
|
return testcase_path.replace(".json", "_test.py")
|
|
elif file_suffix == ".yaml":
|
|
return testcase_path.replace(".yaml", "_test.py")
|
|
elif file_suffix == ".yml":
|
|
return testcase_path.replace(".yml", "_test.py")
|
|
else:
|
|
raise exceptions.ParamsError("")
|
|
|
|
|
|
def format_with_black(tests_path: Text):
|
|
logger.info("format testcases with black ...")
|
|
tests_path = convert_testcase_path(tests_path)
|
|
try:
|
|
subprocess.run(["black", tests_path])
|
|
except subprocess.CalledProcessError as ex:
|
|
logger.error(ex)
|
|
|
|
|
|
def make(tests_path: Text) -> List:
|
|
testcases = []
|
|
if os.path.isdir(tests_path):
|
|
files_list = load_folder_files(tests_path)
|
|
testcases.extend(files_list)
|
|
elif os.path.isfile(tests_path):
|
|
testcases.append(tests_path)
|
|
else:
|
|
raise exceptions.TestcaseNotFound(f"Invalid tests path: {tests_path}")
|
|
|
|
testcase_path_list = []
|
|
for testcase_path in testcases:
|
|
testcase_path = make_testcase(testcase_path)
|
|
if not testcase_path:
|
|
continue
|
|
testcase_path_list.append(testcase_path)
|
|
|
|
format_with_black(tests_path)
|
|
return testcase_path_list
|
|
|
|
|
|
def main_make(tests_paths: List[Text]) -> List:
|
|
testcase_path_list = []
|
|
for tests_path in tests_paths:
|
|
testcase_path_list.extend(make(tests_path))
|
|
|
|
return testcase_path_list
|
|
|
|
|
|
def init_make_parser(subparsers):
|
|
""" make testcases: parse command line options and run commands.
|
|
"""
|
|
parser = subparsers.add_parser(
|
|
"make", help="Convert YAML/JSON testcases to Python unittests.",
|
|
)
|
|
parser.add_argument(
|
|
"testcase_path", nargs="*", help="Specify YAML/JSON testcase file/folder path"
|
|
)
|
|
|
|
return parser
|