httprunner源码学习(三)__make()
mian_make()方法的第12行执行此方法;
打眼一看有点复杂,作者注释的意思大概是使用绝对路径创建testcase,生成pytest文件并缓存;
还是来逐行看吧。
- 31行之前都是对目录/文件的处理(.json .yaml .py)
- 40行读取了 .json .yaml 文件内容,开始进行处理(提取、排序等)
- 42-53行是对异常情况的处理(config不存在、config没有name字段、config不是字典等)
- 第59行开始就是httprunner的核心之一了,用例生成
- 第61行调用了自定义方法:make_testcase,我们去下面会研究一下这个方法
# httprunner/make.py :: __make
def __make(tests_path: Text) -> NoReturn:
""" make testcase(s) with testcase/testsuite/folder absolute path
generated pytest file path will be cached in pytest_files_made_cache_mapping
Args:
tests_path: should be in absolute path
"""
logger.info(f"make path: {tests_path}")
test_files = []
if os.path.isdir(tests_path): # 是目录
files_list = load_folder_files(tests_path) # 自定义方法,作用是返回这个目录下所有以.yml/.yaml/.json/_test.py结尾的文件,返回值是个list。这个递归算法也很有嚼头,建议食用。
test_files.extend(files_list) # 将返回的list存入 test_files
elif os.path.isfile(tests_path): # 如果不是目录
test_files.append(tests_path) # 直接存入 test_files
else:
raise exceptions.TestcaseNotFound(f"Invalid tests path: {tests_path}")
for test_file in test_files:
if test_file.lower().endswith("_test.py"): # 如果文件名小写后以_test.py结尾
pytest_files_run_set.add(test_file) # pytest_files_run_set 是定义在 make.py 的一个全局变量,set类型。
continue
try:
test_content = load_test_file(test_file) # 自定义方法,作用是根据后缀判断文件类型(yaml/json),并返回读取之后的内容(dict)
except (exceptions.FileNotFound, exceptions.FileFormatError) as ex:
logger.warning(f"Invalid test file: {test_file}\n{type(ex).__name__}: {ex}")
continue
if not isinstance(test_content, Dict): # 如果test_content不是dict
logger.warning(
f"Invalid test file: {test_file}\n"
f"reason: test content not in dict format."
)
continue
# api in v2 format, convert to v3 testcase
if "request" in test_content and "name" in test_content: # 如果request 和 name 在读好的json/yaml文件的第一层,执行ensure_testcase_v3_api方法
test_content = ensure_testcase_v3_api(test_content)
if "config" not in test_content:
logger.warning(
f"Invalid testcase/testsuite file: {test_file}\n"
f"reason: missing config part."
)
continue
elif not isinstance(test_content["config"], Dict):
logger.warning(
f"Invalid testcase/testsuite file: {test_file}\n"
f"reason: config should be dict type, got {test_content['config']}"
)
continue
# ensure path absolute
test_content.setdefault("config", {})["path"] = test_file # 给config添加一个键值对: {"path": test_file}
# testcase
if "teststeps" in test_content:
try:
testcase_pytest_path = make_testcase(test_content)
pytest_files_run_set.add(testcase_pytest_path)
except exceptions.TestCaseFormatError as ex:
logger.warning(
f"Invalid testcase file: {test_file}\n{type(ex).__name__}: {ex}"
)
continue
# testsuite
elif "testcases" in test_content:
try:
make_testsuite(test_content)
except exceptions.TestSuiteFormatError as ex:
logger.warning(
f"Invalid testsuite file: {test_file}\n{type(ex).__name__}: {ex}"
)
continue
# invalid format
else:
logger.warning(
f"Invalid test file: {test_file}\n"
f"reason: file content is neither testcase nor testsuite"
)
下一篇httprunner源码学习(四)ensure_testcase_v3_api()、make_testcase()

浙公网安备 33010602011771号