pytest-jequnauto/utils/read_files_tools/case_automatic_control.py

224 lines
8.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
# @Time : 2022/3/28 13:22
# @Author : 李晓杰
"""
import os
import time
from typing import Text, Dict
from common.setting import ensure_path_sep
from utils.read_files_tools.testcase_template import write_testcase_file
from utils.read_files_tools.yaml_control import GetYamlData
from utils.read_files_tools.get_all_files_path import get_all_files
from utils.other_tools.exceptions import ValueNotFoundError
class TestCaseAutomaticGeneration:
"""自动生成自动化测试中的test_case代码"""
@staticmethod
def case_date_path() -> Text:
"""返回 yaml 用例文件路径"""
return ensure_path_sep("\\data")
@staticmethod
def case_path() -> Text:
""" 存放用例代码路径"""
return ensure_path_sep("\\test_case")
def file_name(self, file: Text) -> Text:
"""
通过 yaml文件的命名将名称转换成 py文件的名称
:param file: yaml 文件路径
:return: 示例: DateDemo.py
"""
i = len(self.case_date_path())
yaml_path = file[i:]
file_name = None
# 路径转换
if '.yaml' in yaml_path:
file_name = yaml_path.replace('.yaml', '.py')
elif '.yml' in yaml_path:
file_name = yaml_path.replace('.yml', '.py')
return file_name
def get_case_path(self, file_path: Text) -> tuple:
"""
根据 yaml 中的用例,生成对应 testCase 层代码的路径
:param file_path: yaml用例路径
:return: D:\\Project\\test_case\\test_case_demo.py, test_case_demo.py
"""
# 这里通过“\\” 符号进行分割,提取出来文件名称 os.sep表示分隔符/或者\.windows 就是\\
path = self.file_name(file_path).split(os.sep)
# 判断生成的 testcase 文件名称需要以test_ 开头 (就是在加了个test_在前面)
case_name = path[-1] = path[-1].replace(path[-1], "test_" + path[-1])
new_name = os.sep.join(path)
# test_case目录必须在根目录pytest_auto_api2下
return ensure_path_sep("\\test_case" + new_name), case_name
def get_test_class_title(self, file_path: Text) -> Text:
"""
自动生成类名称
:param file_path:
:return: sup_apply_list --> SupApplyList
1.传入F:\JACK\My_project\pytest-auto-api2\data\Collect\collect_addtool.yaml
2.通过self.file_name(file_path) -->Collect\collect_addtool.py
3.然后os.path.split 返回一个目录和文件名 Collectcollect_addtool.py (字典)
4.通过[1][:-3] 取到第二个文件,去除.py -->collect_addtool
5.split 按"_"分隔-> colect,addtool
6.len() 获取长度 "2"
7.按长度循环遍历把每个字符字母变大写capitalize() 将字符串的第一个字母变成大写,其他字母变小写
8.然后再拼接回去,返回
"""
# 提取文件名称
_file_name = os.path.split(self.file_name(file_path))[1][:-3]
_name = _file_name.split("_")
_name_len = len(_name)
# 将文件名称格式,转换成类名称: sup_apply_list --> SupApplyList
for i in range(_name_len):
_name[i] = _name[i].capitalize()
_class_name = "".join(_name)
# CollectToolList 'str'
return _class_name
@staticmethod
def error_message(param_name, file_path):
"""
用例中填写不正确的相关提示
:return:
"""
msg = f"用例中未找到 {param_name} 参数值,请检查新增的用例中是否填写对应的参数内容" \
"如已填写,可能是 yaml 参数缩进不正确\n" \
f"用例路径: {file_path}"
return msg
def func_title(self, file_path: Text) -> Text:
"""
函数名称
:param file_path: yaml 用例路径
:return:
"""
_file_name = os.path.split(self.file_name(file_path))[1][:-3]
return _file_name
@staticmethod
def allure_epic(case_data: Dict, file_path) -> Text:
"""
用于 allure 报告装饰器中的内容 @allure.epic("项目名称")
:param file_path: 用例路径
:param case_data: 用例数据
:return:
"""
try:
return case_data['case_common']['allureEpic']
except KeyError as exc:
raise ValueNotFoundError(TestCaseAutomaticGeneration.error_message(
param_name="allureEpic",
file_path=file_path
)) from exc
@staticmethod
def allure_feature(case_data: Dict, file_path) -> Text:
"""
用于 allure 报告装饰器中的内容 @allure.feature("模块名称")
:param file_path:
:param case_data:
:return:
"""
try:
return case_data['case_common']['allureFeature']
except KeyError as exc:
raise ValueNotFoundError(TestCaseAutomaticGeneration.error_message(
param_name="allureFeature",
file_path=file_path
)) from exc
@staticmethod
def allure_story(case_data: Dict, file_path) -> Text:
"""
用于 allure 报告装饰器中的内容 @allure.story("测试功能")
:param file_path:
:param case_data:
:return:
"""
try:
return case_data['case_common']['allureStory']
except KeyError as exc:
raise ValueNotFoundError(TestCaseAutomaticGeneration.error_message(
param_name="allureStory",
file_path=file_path
)) from exc
def mk_dir(self, file_path: Text) -> None:
""" 判断生成自动化代码的文件夹路径是否存在,如果不存在,则自动创建 """
# _LibDirPath = os.path.split(self.libPagePath(filePath))[0]
_case_dir_path = os.path.split(self.get_case_path(file_path)[0])[0]
if not os.path.exists(_case_dir_path):
os.makedirs(_case_dir_path)
@staticmethod
def case_ids(test_case):
"""
获取用例 ID
:param test_case: 测试用例内容
:return:
"""
ids = []
for k, v in test_case.items():
if k != "case_common":
ids.append(k)
# 把yaml中所有的key 都放在ids 的列表内
return ids
def yaml_path(self, file_path: Text) -> Text:
"""
生成动态 yaml 路径, 主要处理业务分层场景
:param file_path: 如业务有多个层级, 则获取到每一层/test_demo/DateDemo.py
:return: Login/common.yaml
"""
i = len(self.case_date_path())
# 兼容 linux 和 window 操作路径
yaml_path = file_path[i:].replace("\\", "/")
return yaml_path
def get_case_automatic(self) -> None:
""" 自动生成 测试代码"""
"""
1. 获取data文件下yaml文件的所有绝对路径
2. 判断是否有'proxy_data.yaml'文件,否才生成测试代码
3. 遍历调用mk_dir():里面会判断test_case 是否有test_*.py文件没有则调用os.makedirs自动生成
4. GetYamlDate(file)
"""
# 返回的是路径一个字典
file_path = get_all_files(file_path=ensure_path_sep("\\data"), yaml_data_switch=True)
for file in file_path:
# 判断代理拦截的yaml文件不生成test_case代码
if 'proxy_data.yaml' not in file:
# 判断用例需要用的文件夹路径是否存在,不存在则创建
self.mk_dir(file)
yaml_case_process = GetYamlData(file).get_yaml_data()
self.case_ids(yaml_case_process)
write_testcase_file(
allure_epic=self.allure_epic(case_data=yaml_case_process, file_path=file),
allure_feature=self.allure_feature(yaml_case_process, file_path=file),
# file :data\\下面的文件
class_title=self.get_test_class_title(file),
func_title=self.func_title(file),
# D:\\Project\\test_case\\test_case_demo.py
case_path=self.get_case_path(file)[0],
# yaml_case_process 是一个yaml 字典
case_ids=self.case_ids(yaml_case_process),
# test_case_demo.dy
file_name=self.get_case_path(file)[1],
allure_story=self.allure_story(case_data=yaml_case_process, file_path=file)
)
if __name__ == '__main__':
TestCaseAutomaticGeneration().get_case_automatic()