init: 初始化项目
- 创建了基本的项目结构 - 添加了 .gitignore 文件 - 配置了基本的开发环境 - 添加清华镜像源 - 设置了基础的文件夹和文件(如 commons, utils, POM, pytest.ini) 项目说明: - [项目名称]:Web自动化测试 - [项目描述]:基于pytest,selenium的自动化测试工具 - [开发环境]:Python
This commit is contained in:
11
utils/file_processors/__init__.py
Normal file
11
utils/file_processors/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: __init__.py
|
||||
@date: 2025/3/4 17:23
|
||||
@desc:
|
||||
"""
|
||||
41
utils/file_processors/base.py
Normal file
41
utils/file_processors/base.py
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: base
|
||||
@date: 2025/3/4 17:23
|
||||
@desc:
|
||||
"""
|
||||
import abc
|
||||
|
||||
|
||||
class BaseFileProcessor(abc.ABC): # 使用 abc 模块定义抽象基类
|
||||
"""
|
||||
文件处理器的抽象基类。
|
||||
定义了所有子类必须实现的方法。
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load(self):
|
||||
"""加载."""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def to_string(data: dict) -> str:
|
||||
"""将文件内容转换为字符串。"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def to_dict(data: str) -> dict:
|
||||
"""将文件内容转换为字典。"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def save(self, new_filepath=None):
|
||||
"""将数据保存."""
|
||||
pass
|
||||
42
utils/file_processors/file_handle.py
Normal file
42
utils/file_processors/file_handle.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: file_handle
|
||||
@date: 2025/3/7 09:31
|
||||
@desc:
|
||||
"""
|
||||
|
||||
from utils.file_processors.toml_processor import TomlProcessor
|
||||
from utils.file_processors.yaml_processor import YamlProcessor
|
||||
from utils.file_processors.json_processor import JsonProcessor
|
||||
from commons.settings import configs
|
||||
processors = {
|
||||
'toml': TomlProcessor,# 暂不支持
|
||||
'yaml': YamlProcessor,
|
||||
'yml': YamlProcessor,
|
||||
'json': JsonProcessor,
|
||||
|
||||
}
|
||||
|
||||
|
||||
def get_processor(ext):
|
||||
agent_model = processors.get(ext, YamlProcessor) # 代理模式
|
||||
|
||||
return agent_model # 默认回退到 Yaml
|
||||
|
||||
|
||||
FileHandle = get_processor("yaml")
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 示例用法
|
||||
yaml_file = FileHandle(configs.variable)
|
||||
print(yaml_file)
|
||||
print(type(yaml_file))
|
||||
file_string = FileHandle.to_string(yaml_file)
|
||||
print(file_string)
|
||||
file_dict = FileHandle.to_dict(file_string)
|
||||
print(file_dict)
|
||||
126
utils/file_processors/json_processor.py
Normal file
126
utils/file_processors/json_processor.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: yaml_processor
|
||||
@date: 2025/3/4 17:28
|
||||
@desc:
|
||||
"""
|
||||
import logging
|
||||
from typing import Union
|
||||
from pathlib import Path
|
||||
import json
|
||||
from utils.file_processors.base import BaseFileProcessor
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class JsonProcessor(BaseFileProcessor, dict):
|
||||
"""
|
||||
用于处理 YAML 文件的类,继承自 dict。
|
||||
提供了从文件加载、保存到文件、转换为字符串和从字符串转换的功能,
|
||||
并可以直接像字典一样访问 YAML 数据。
|
||||
"""
|
||||
|
||||
def __init__(self, filepath: Union[str, Path], data: Union[dict, None] = None):
|
||||
"""
|
||||
初始化 YamlFile 对象。
|
||||
|
||||
Args:
|
||||
filepath: YAML 文件的路径 (可以是字符串或 pathlib.Path 对象).
|
||||
data: 可选的初始数据字典。如果提供,则用该字典初始化 YamlFile。
|
||||
如果不提供,则尝试从 filepath 加载数据。
|
||||
"""
|
||||
super().__init__() # 初始化父类 dict
|
||||
self.filepath: Path = Path(filepath) # 确保 filepath 是 Path 对象
|
||||
if data is not None:
|
||||
self.update(data) # 如果提供了初始数据,则更新字典
|
||||
else:
|
||||
self.load() # 否则,尝试从文件加载
|
||||
|
||||
def load(self) -> None:
|
||||
"""
|
||||
从 YAML 文件加载数据并更新字典。
|
||||
如果文件不存在或加载失败,则清空字典并记录警告/错误。
|
||||
"""
|
||||
self.clear() # 清空现有数据
|
||||
if self.filepath.exists():
|
||||
try:
|
||||
with open(self.filepath, "r", encoding="utf-8") as f:
|
||||
loaded_data = json.load(f) or {}
|
||||
self.update(loaded_data) # 使用加载的数据更新字典
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"加载 YAML 文件 {self.filepath} 时出错: {e}")
|
||||
# 保持字典为空 (已在开头 clear)
|
||||
else:
|
||||
logger.warning(f"文件 {self.filepath} 不存在, 字典保持为空.")
|
||||
# 保持字典为空 (已在开头 clear)
|
||||
|
||||
@staticmethod
|
||||
def to_string(data: dict) -> str:
|
||||
"""
|
||||
将字典 (自身) 转换为 YAML 格式的字符串。
|
||||
|
||||
Returns:
|
||||
YAML 格式的字符串。
|
||||
"""
|
||||
try:
|
||||
return json.dumps(
|
||||
dict(data), # 使用dict转换为标准的字典
|
||||
ensure_ascii=False, # 允许非ASCII字符
|
||||
# indent=4, # 美化输出,缩进4个空格
|
||||
sort_keys=False # 不排序键
|
||||
)
|
||||
except TypeError as e:
|
||||
logger.error(f"将数据转换为 JSON 字符串时出错: {e}")
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def to_dict(data: str) -> None:
|
||||
"""
|
||||
将 YAML 格式的字符串转换为字典,并更新当前字典的内容.
|
||||
|
||||
Args:
|
||||
data: YAML 格式的字符串。
|
||||
"""
|
||||
try:
|
||||
loaded_data = json.loads(data) or {}
|
||||
return loaded_data
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"将 JSON 字符串转换为字典时出错: {e}")
|
||||
|
||||
def save(self, new_filepath: Union[str, Path, None] = None):
|
||||
"""
|
||||
将字典数据 (自身) 保存到 YAML 文件。
|
||||
|
||||
Args:
|
||||
new_filepath: 可选参数,指定新的文件路径。如果为 None,则覆盖原文件。
|
||||
"""
|
||||
filepath = Path(new_filepath) if new_filepath else self.filepath
|
||||
|
||||
try:
|
||||
with open(filepath, "w", encoding="utf-8") as f:
|
||||
json.dump(
|
||||
dict(self), # 使用dict转换为标准的字典
|
||||
f,
|
||||
ensure_ascii=False, # 允许非ASCII字符
|
||||
indent=4, # 美化输出,缩进4个空格
|
||||
sort_keys=False # 不排序键
|
||||
)
|
||||
except (TypeError, OSError) as e:
|
||||
logger.error(f"保存 JSON 文件 {filepath} 时出错: {e}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 示例用法
|
||||
json_path = r'E:\PyP\InterfaceAutoTest\TestCases\test_1_user.json' # 你的 JSON 文件路径
|
||||
json_file = JsonProcessor(json_path)
|
||||
print(json_file)
|
||||
print(type(json_file))
|
||||
json_string = JsonProcessor.to_string(json_file)
|
||||
JsonProcessor.to_dict(json_string)
|
||||
print(json_string)
|
||||
json_file.save()
|
||||
110
utils/file_processors/toml_processor.py
Normal file
110
utils/file_processors/toml_processor.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: file_processing
|
||||
@date: 2025/4/8 21:22
|
||||
@desc:
|
||||
"""
|
||||
from pathlib import Path
|
||||
from tomlkit import parse, dumps
|
||||
from tomlkit.toml_file import TOMLFile
|
||||
|
||||
import logging
|
||||
from typing import Union
|
||||
from dataclasses import dataclass, asdict, field
|
||||
from pathlib import Path
|
||||
import tomlkit
|
||||
from utils.file_processors.base import BaseFileProcessor
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TomlProcessor(BaseFileProcessor, dict):
|
||||
"""
|
||||
用于处理 YAML 文件的类,继承自 dict。
|
||||
提供了从文件加载、保存到文件、转换为字符串和从字符串转换的功能,
|
||||
并可以直接像字典一样访问 YAML 数据。
|
||||
"""
|
||||
|
||||
def __init__(self, filepath: Union[str, Path], data: Union[dict, None] = None):
|
||||
"""
|
||||
初始化 YamlFile 对象。
|
||||
|
||||
Args:
|
||||
filepath: YAML 文件的路径 (可以是字符串或 pathlib.Path 对象).
|
||||
data: 可选的初始数据字典。如果提供,则用该字典初始化 YamlFile。
|
||||
如果不提供,则尝试从 filepath 加载数据。
|
||||
"""
|
||||
super().__init__() # 初始化父类 dict
|
||||
self.filepath: Path = Path(filepath) # 确保 filepath 是 Path 对象
|
||||
if data is not None:
|
||||
self.update(data) # 如果提供了初始数据,则更新字典
|
||||
else:
|
||||
self.load() # 否则,尝试从文件加载
|
||||
|
||||
def load(self) -> None:
|
||||
|
||||
self.clear() # 清空现有数据
|
||||
if self.filepath.exists():
|
||||
try:
|
||||
with open(self.filepath, 'r', encoding='utf-8') as f:
|
||||
result = tomlkit.parse(f.read()) or {}
|
||||
# print(result)
|
||||
self.update(result)
|
||||
except Exception as e:
|
||||
logger.error(f"加载 TOML 文件 {self.filepath} 时出错: {e}")
|
||||
else:
|
||||
logger.warning(f"文件 {self.filepath} 不存在, 字典保持为空.")
|
||||
@staticmethod
|
||||
def to_string(data: dict) -> str:
|
||||
try:
|
||||
return tomlkit.dumps(
|
||||
dict(data), # 使用dict转换为标准的字典
|
||||
sort_keys=False
|
||||
)
|
||||
except TypeError as e:
|
||||
logger.error(f"将数据转换为 TOML 字符串时出错: {e}")
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def to_dict(data: str) -> Union[None, dict]:
|
||||
try:
|
||||
loaded_data = tomlkit.loads(data) or {}
|
||||
return loaded_data
|
||||
except Exception as e:
|
||||
logger.error(f"将 TOML 字符串转换为字典时出错: {e}")
|
||||
|
||||
def save(self, new_filepath: Union[str, Path, None] = None):
|
||||
|
||||
filepath = Path(new_filepath) if new_filepath else self.filepath
|
||||
|
||||
try:
|
||||
with open(filepath, "w", encoding="utf-8") as f:
|
||||
tomlkit.dump(
|
||||
dict(self), # 使用dict转换为标准的字典
|
||||
fp=f,
|
||||
sort_keys=False,
|
||||
)
|
||||
except (TypeError, OSError) as e:
|
||||
logger.error(f"保存 TOML 文件 {filepath} 时出错: {e}")
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
...
|
||||
toml_path =r'E:\PyP\WebAutoTest\data\var.toml'
|
||||
toml_file = TomlProcessor(toml_path)
|
||||
print(toml_file)
|
||||
print(type(toml_file))
|
||||
print(toml_file.to_string(toml_file))
|
||||
print(toml_file.to_dict(toml_file.to_string(toml_file)))
|
||||
print(toml_file.to_dict(toml_file.to_string(toml_file)))
|
||||
toml_file.to_dict(toml_file.to_string(toml_file))
|
||||
# toml_file.save()
|
||||
|
||||
print(toml_file.to_string(
|
||||
{'用例ID': None, '内容': '打开浏览器', '标记': 'browser', '参数': 'edge', '_BlankField': [None, None]}))
|
||||
127
utils/file_processors/yaml_processor.py
Normal file
127
utils/file_processors/yaml_processor.py
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: yaml_processor
|
||||
@date: 2025/3/4 17:28
|
||||
@desc:
|
||||
"""
|
||||
import logging
|
||||
from typing import Union
|
||||
from dataclasses import dataclass, asdict, field
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
from utils.file_processors.base import BaseFileProcessor
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class YamlProcessor(BaseFileProcessor, dict):
|
||||
"""
|
||||
用于处理 YAML 文件的类,继承自 dict。
|
||||
提供了从文件加载、保存到文件、转换为字符串和从字符串转换的功能,
|
||||
并可以直接像字典一样访问 YAML 数据。
|
||||
"""
|
||||
|
||||
def __init__(self, filepath: Union[str, Path], data: Union[dict, None] = None):
|
||||
"""
|
||||
初始化 YamlFile 对象。
|
||||
|
||||
Args:
|
||||
filepath: YAML 文件的路径 (可以是字符串或 pathlib.Path 对象).
|
||||
data: 可选的初始数据字典。如果提供,则用该字典初始化 YamlFile。
|
||||
如果不提供,则尝试从 filepath 加载数据。
|
||||
"""
|
||||
super().__init__() # 初始化父类 dict
|
||||
self.filepath: Path = Path(filepath) # 确保 filepath 是 Path 对象
|
||||
if data is not None:
|
||||
self.update(data) # 如果提供了初始数据,则更新字典
|
||||
else:
|
||||
self.load() # 否则,尝试从文件加载
|
||||
|
||||
def load(self) -> None:
|
||||
"""
|
||||
从 YAML 文件加载数据并更新字典。
|
||||
如果文件不存在或加载失败,则清空字典并记录警告/错误。
|
||||
"""
|
||||
self.clear() # 清空现有数据
|
||||
if self.filepath.exists():
|
||||
try:
|
||||
with open(self.filepath, "r", encoding="utf-8") as f:
|
||||
loaded_data = yaml.safe_load(f) or {}
|
||||
self.update(loaded_data) # 使用加载的数据更新字典
|
||||
except yaml.YAMLError as e:
|
||||
logger.error(f"加载 YAML 文件 {self.filepath} 时出错: {e}")
|
||||
# 保持字典为空 (已在开头 clear)
|
||||
else:
|
||||
logger.warning(f"文件 {self.filepath} 不存在, 字典保持为空.")
|
||||
# 保持字典为空 (已在开头 clear)
|
||||
|
||||
@staticmethod
|
||||
def to_string(data: dict) -> str:
|
||||
"""
|
||||
将字典 (自身) 转换为 YAML 格式的字符串。
|
||||
|
||||
Returns:
|
||||
YAML 格式的字符串。
|
||||
"""
|
||||
try:
|
||||
return yaml.safe_dump(
|
||||
dict(data), # 使用dict转换为标准的字典
|
||||
allow_unicode=True,
|
||||
sort_keys=False,
|
||||
default_flow_style=False
|
||||
)
|
||||
except TypeError as e:
|
||||
logger.error(f"将数据转换为 YAML 字符串时出错: {e}")
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def to_dict(data: str) -> Union[None, dict]:
|
||||
"""
|
||||
将 YAML 格式的字符串转换为字典,并更新当前字典的内容.
|
||||
|
||||
Args:
|
||||
data: YAML 格式的字符串。
|
||||
"""
|
||||
try:
|
||||
loaded_data = yaml.safe_load(data) or {}
|
||||
return loaded_data
|
||||
except yaml.YAMLError as e:
|
||||
logger.error(f"将 YAML 字符串转换为字典时出错: {e}")
|
||||
|
||||
def save(self, new_filepath: Union[str, Path, None] = None):
|
||||
"""
|
||||
将字典数据 (自身) 保存到 YAML 文件。
|
||||
|
||||
Args:
|
||||
new_filepath: 可选参数,指定新的文件路径。如果为 None,则覆盖原文件。
|
||||
"""
|
||||
filepath = Path(new_filepath) if new_filepath else self.filepath
|
||||
|
||||
try:
|
||||
with open(filepath, "w", encoding="utf-8") as f:
|
||||
yaml.safe_dump(
|
||||
dict(self), # 使用dict转换为标准的字典
|
||||
stream=f,
|
||||
allow_unicode=True,
|
||||
sort_keys=False,
|
||||
default_flow_style=False
|
||||
)
|
||||
except (TypeError, OSError) as e:
|
||||
logger.error(f"保存 YAML 文件 {filepath} 时出错: {e}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 示例用法
|
||||
yaml_path = r'E:\PyP\InterfaceAutoTest\TestCases\answer\test_1_status.yaml' # 你的 YAML 文件路径
|
||||
yaml_file = YamlProcessor(yaml_path)
|
||||
print(yaml_file)
|
||||
print(type(yaml_file))
|
||||
|
||||
Reference in New Issue
Block a user