refactor(models): 优化项目
- 重构assert_all - 优化目录结构
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -3,6 +3,6 @@
|
||||
.venv/
|
||||
poetry.lock
|
||||
.pytest_cache/
|
||||
report
|
||||
temp
|
||||
logs
|
||||
report/
|
||||
temp/
|
||||
logs/
|
||||
@@ -14,11 +14,13 @@ import logging
|
||||
|
||||
import allure
|
||||
import pytest
|
||||
|
||||
from commons import settings
|
||||
from commons.files import YamlFile
|
||||
from commons.models import CaseInfo
|
||||
from commons.session import Session
|
||||
from commons.exchange import Exchange
|
||||
from commons import settings
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -31,7 +33,6 @@ exchanger = Exchange(settings.exchanger)
|
||||
|
||||
@allure.epic("项目名称:answer")
|
||||
class TestAPI:
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def find_yaml_case(cls, case_path: Path = _case_path):
|
||||
@@ -41,12 +42,12 @@ class TestAPI:
|
||||
"""
|
||||
yaml_path_list = case_path.glob("**/test_*.yaml") # 搜索当前目录及其子目录下以test_开头yaml为后缀的文件
|
||||
for yaml_path in yaml_path_list:
|
||||
# logger.info(f"load file {yaml_path=}")
|
||||
logger.info(f"加载文件:{yaml_path}")
|
||||
|
||||
file = YamlFile(yaml_path) # 自动读取yaml文件
|
||||
case_info = CaseInfo(**file) # 校验yaml格式
|
||||
|
||||
# logger.info(f"case_info={case_info.to_yaml()}") # 把case_info 转成字符串,然后记录日志
|
||||
logger.info(f"case_info={case_info.to_yaml()}") # 把case_info 转成字符串,然后记录日志
|
||||
|
||||
case_func = cls.new_case(case_info) # 从yaml格式转换为pytest格式
|
||||
print(yaml_path.stem)
|
||||
@@ -59,6 +60,7 @@ class TestAPI:
|
||||
|
||||
ddt_title = [data.title for data in ddt_data]
|
||||
logger.info(f"{ddt_title=}")
|
||||
|
||||
@allure.feature(case_info.feature)
|
||||
@allure.story(case_info.story)
|
||||
@pytest.mark.parametrize("case_info", ddt_data, ids=ddt_title)
|
||||
|
||||
@@ -90,7 +90,7 @@ if __name__ == '__main__':
|
||||
exchanger.extract(mock_resp, "age", "json", '$.age', 0)
|
||||
exchanger.extract(mock_resp, "data", "json", '$.data', 0)
|
||||
exchanger.extract(mock_resp, "aaa", "json", '$.aaa', 0)
|
||||
case_info = CaseInfo(
|
||||
mock_case_info = CaseInfo(
|
||||
title="单元测试",
|
||||
request={
|
||||
"data":
|
||||
@@ -99,5 +99,5 @@ if __name__ == '__main__':
|
||||
extract={},
|
||||
validate={}
|
||||
)
|
||||
new_case_info = exchanger.replace(case_info)
|
||||
print(new_case_info)
|
||||
new_mock_case_info = exchanger.replace(mock_case_info)
|
||||
print(new_mock_case_info)
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
import logging
|
||||
|
||||
import yaml
|
||||
from commons.models import CaseInfo
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class YamlFile(dict):
|
||||
def __init__(self, path):
|
||||
super().__init__()
|
||||
@@ -34,10 +34,13 @@ class YamlFile(dict):
|
||||
dict(self),
|
||||
stream=f,
|
||||
allow_unicode=True, # allow_unicode:使用unicode编码正常显示中文
|
||||
sort_keys=False) # sort_keys:保持原有排序
|
||||
sort_keys=False # sort_keys:保持原有排序
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from commons.models import CaseInfo
|
||||
|
||||
yaml_path = r'E:\PyP\InterfaceAutoTest\TestCases\test_1_user.yaml'
|
||||
yaml_file = YamlFile(yaml_path)
|
||||
# yaml_file.load()
|
||||
|
||||
@@ -17,7 +17,7 @@ import hashlib
|
||||
|
||||
from commons.databases import db
|
||||
|
||||
# from commons.files import YamlFile
|
||||
from commons.files import YamlFile
|
||||
from commons import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -53,7 +53,7 @@ def new_id():
|
||||
def last_id() -> str:
|
||||
# 不自增,只返回结果
|
||||
|
||||
id_file = YamlFile("id.yaml")
|
||||
id_file = YamlFile(settings.id_path)
|
||||
return id_file["id"]
|
||||
|
||||
|
||||
@@ -97,8 +97,5 @@ def rsa_decode(content: str) -> str:
|
||||
if __name__ == '__main__':
|
||||
# res = url_unquote("%E6%88%90%E5%8A%9F%E3%80%82")
|
||||
# print(res)
|
||||
a = "这是中文dddddd"
|
||||
bb = base64_encode(a)
|
||||
print(bb)
|
||||
cc = base64_decode(bb)
|
||||
print(cc)
|
||||
print(f"计数器:{new_id()}")
|
||||
print(f"当前数值:{last_id()}")
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
@desc: 声明yaml用例格式
|
||||
"""
|
||||
import logging
|
||||
from dataclasses import dataclass, asdict
|
||||
from dataclasses import dataclass, asdict, field
|
||||
|
||||
import allure
|
||||
import yaml
|
||||
|
||||
from commons.templates import Template
|
||||
from commons import settings
|
||||
from utils import case_validator
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -27,7 +28,7 @@ class CaseInfo:
|
||||
request: dict
|
||||
extract: dict
|
||||
validate: dict
|
||||
parametrize: list = ""
|
||||
parametrize: list = field(default_factory=list)
|
||||
epic: str = settings.allure_epic
|
||||
feature: str = settings.allure_feature
|
||||
story: str = settings.allure_story
|
||||
@@ -48,26 +49,29 @@ class CaseInfo:
|
||||
|
||||
@allure.step("断言")
|
||||
def assert_all(self):
|
||||
if not self.validate:
|
||||
return
|
||||
for assert_type, assert_value in self.validate.items():
|
||||
for msg, data in assert_value.items():
|
||||
a, b = data[0], data[1]
|
||||
# print(assert_type, a, b, msg)
|
||||
match assert_type:
|
||||
case 'equals':
|
||||
logger.info(f"assert {a} == {b}, {msg}")
|
||||
assert a == b, msg
|
||||
case 'not_equals':
|
||||
logger.info(f"assert {a} != {b}, {msg}")
|
||||
assert a != b, msg
|
||||
case 'contains':
|
||||
logger.info(f"assert {a} in {b}, {msg}")
|
||||
assert a in b, msg
|
||||
case 'not_contains':
|
||||
logger.info(f"assert {a} not in {b}, {msg}")
|
||||
assert a not in b, msg
|
||||
# case "xxxxx
|
||||
_validator = case_validator.CaseValidator()
|
||||
# print(case_validator.VALIDATORS)
|
||||
_validator.assert_all(self.validate)
|
||||
# if not self.validate:
|
||||
# return
|
||||
# for assert_type, assert_value in self.validate.items():
|
||||
# for msg, data in assert_value.items():
|
||||
# a, b = data[0], data[1]
|
||||
# # print(assert_type, a, b, msg)
|
||||
# match assert_type:
|
||||
# case 'equals':
|
||||
# logger.info(f"assert {a} == {b}, {msg}")
|
||||
# assert a == b, msg
|
||||
# case 'not_equals':
|
||||
# logger.info(f"assert {a} != {b}, {msg}")
|
||||
# assert a != b, msg
|
||||
# case 'contains':
|
||||
# logger.info(f"assert {a} in {b}, {msg}")
|
||||
# assert a in b, msg
|
||||
# case 'not_contains':
|
||||
# logger.info(f"assert {a} not in {b}, {msg}")
|
||||
# assert a not in b, msg
|
||||
# case "xxxxx
|
||||
|
||||
def ddt(self) -> list: # 返回一个列表,列表中应该包含N个注入了变量的caseInfo
|
||||
case_list = []
|
||||
|
||||
@@ -13,15 +13,15 @@ from pathlib import Path
|
||||
|
||||
root_path = (Path(__file__)).resolve().parents[1]
|
||||
|
||||
base_url = 'http://127.0.0.1:40065'
|
||||
base_url = 'http://119.91.19.171:40065'
|
||||
case_path = rf"{root_path}\TestCases\answer"
|
||||
exchanger = rf"{root_path}\extract.yaml"
|
||||
id_path = rf"{root_path}\id.yaml"
|
||||
|
||||
db_host = '127.0.0.1' # ip
|
||||
db_host = '119.91.19.171' # ip
|
||||
db_port = 3306 # 端口
|
||||
db_user = 'root' # 用户名
|
||||
db_password = 'password' # 密码
|
||||
db_password = 'mysql_hNahSe' # 密码
|
||||
db_database = 'answer' # 库名
|
||||
|
||||
allure_epic: str = "项目名称:answer"
|
||||
|
||||
@@ -13,6 +13,7 @@ import copy
|
||||
import logging
|
||||
import re
|
||||
import string
|
||||
import inspect
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -58,7 +59,7 @@ class Template(string.Template):
|
||||
func = mapping.get(func_name) # 读取指定函数
|
||||
func_args_value = [mapping.get(arg, arg) for arg in func_args]
|
||||
|
||||
if func_args_value == [""]: # 处理没有参数的func
|
||||
if func_args_value == [""]: # 处理没有参数的func
|
||||
func_args_value = []
|
||||
|
||||
if not callable(func):
|
||||
@@ -75,8 +76,13 @@ def hot_load():
|
||||
if func_name.startswith("_"):
|
||||
continue
|
||||
func_code = getattr(funcs, func_name) # 取到函数对象
|
||||
# print(func_code)
|
||||
if callable(func_code): # 如果是一个可以调用的函数
|
||||
Template.func_mapping[func_name] = func_code # 函数放到Template中
|
||||
print(Template.func_mapping)
|
||||
# if inspect.isfunction(func_code): # 如果是一个可以调用的函数
|
||||
# Template.func_mapping[func_name] = func_code # 函数放到Template中
|
||||
# print(Template.func_mapping)
|
||||
|
||||
|
||||
hot_load()
|
||||
|
||||
@@ -1,18 +1,69 @@
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.find_yaml_case:44 - load file yaml_path=WindowsPath('E:/PyP/InterfaceAutoTest/TestCases/test_1_user.yaml')'
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.find_yaml_case:44 - load file yaml_path=WindowsPath('E:/PyP/InterfaceAutoTest/TestCases/test_2_url.yaml')'
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.find_yaml_case:44 - load file yaml_path=WindowsPath('E:/PyP/InterfaceAutoTest/TestCases/test_3_sql.yaml')'
|
||||
''02/23/2025 10:17:34 PM' [pytest_result_log] INFO plugin.pytest_runtest_setup:122 - ---------------Start: main.py::TestAPI::test_1_user.yaml[查询用户信息0]---------------'
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.test_func:67 - =================================用例开始执行:查询用户信息=================================='
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.test_func:71 - 1,正在注入变量...'
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.test_func:74 - 2,正在请求接口...'
|
||||
''02/23/2025 10:17:34 PM' [requests.session] INFO session.send:36 - 发送请求>>>>>> 接口地址 = GET http://119.91.19.171:40065/answer/api/v1/connector/info'
|
||||
''02/23/2025 10:17:34 PM' [requests.session] INFO session.send:37 - 发送请求>>>>>> 请求头 = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Accept-Language': 'zh_CN', 'Content-Type': 'application/json', 'Cookie': 'psession=33c6c2de-7e5d-40e2-9bbc-3c637a690c3f; lang=zh-CN; 3x-ui=MTcyNjU2NDcwOHxEWDhFQVFMX2dBQUJFQUVRQUFCMV80QUFBUVp6ZEhKcGJtY01EQUFLVEU5SFNVNWZWVk5GVWhoNExYVnBMMlJoZEdGaVlYTmxMMjF2WkdWc0xsVnpaWExfZ1FNQkFRUlZjMlZ5QWYtQ0FBRUVBUUpKWkFFRUFBRUlWWE5sY201aGJXVUJEQUFCQ0ZCaGMzTjNiM0prQVF3QUFRdE1iMmRwYmxObFkzSmxkQUVNQUFBQUdQLUNGUUVDQVFkNGRXa3lNREkwQVFkNGRXa3lNREkwQUE9PXwLOhLRIDjzvQ3oI-UF-GhkMheEENkxRJ8GkAZ79eFHvg==', 'Host': '119.91.19.171:40065', 'Origin': 'http://119.91.19.171:40065', 'Referer': 'http://119.91.19.171:40065/users/login'}'
|
||||
''02/23/2025 10:17:34 PM' [requests.session] INFO session.send:38 - 发送请求>>>>>> 请求正文 = None '
|
||||
''02/23/2025 10:17:34 PM' [requests.session] INFO session.send:42 - 接收响应 <<<<<< 状态码 = 200'
|
||||
''02/23/2025 10:17:34 PM' [requests.session] INFO session.send:43 - 接收响应 <<<<<< 响应头 = {'Content-Type': 'application/json; charset=utf-8', 'Date': 'Sun, 23 Feb 2025 14:17:34 GMT', 'Content-Length': '64'}'
|
||||
''02/23/2025 10:17:34 PM' [requests.session] INFO session.send:44 - 接收响应 <<<<<< 响应正文 = {'code': 200, 'reason': 'base.success', 'msg': '成功。', 'data': []}'
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.test_func:77 - 3,正在提取变量...'
|
||||
''02/23/2025 10:17:34 PM' [commons.cases] INFO cases.test_func:83 - 4,正在断言...'
|
||||
''02/23/2025 10:17:34 PM' [commons.models] INFO models.assert_all:59 - assert 200 == code1, 状态码等于200'
|
||||
''02/23/2025 10:17:34 PM' [pytest_result_log] ERROR plugin.pytest_result_log:190 - test status is FAILED (main.py::TestAPI::test_1_user.yaml[查询用户信息0]): AssertionError'
|
||||
''02/23/2025 10:17:34 PM' [pytest_result_log] INFO plugin.pytest_runtest_teardown:128 - ----------------End: main.py::TestAPI::test_1_user.yaml[查询用户信息0]----------------'
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.find_yaml_case:45 - 加载文件:D:\CNWei\CNW\InterfaceAutoTest\TestCases\answer\test_1_status.yaml
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.find_yaml_case:50 - case_info=title: 查询状态信息
|
||||
request:
|
||||
method: get
|
||||
url: /answer/api/v1/connector/info
|
||||
headers:
|
||||
Host: 119.91.19.171:40065
|
||||
Accept-Language: en_US
|
||||
Accept: application/json, text/plain, */*
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
|
||||
like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
|
||||
Referer: http://119.91.19.171:40065/users/login
|
||||
Accept-Encoding: gzip, deflate
|
||||
extract:
|
||||
code:
|
||||
- json
|
||||
- $.code
|
||||
- 0
|
||||
msg:
|
||||
- json
|
||||
- $.msg
|
||||
- 0
|
||||
validate:
|
||||
equals:
|
||||
状态码等于200:
|
||||
- Success.
|
||||
- ${msg}
|
||||
parametrize:
|
||||
- - title
|
||||
- username
|
||||
- password
|
||||
- code
|
||||
- - 测试1
|
||||
- user1
|
||||
- pass1
|
||||
- code1
|
||||
- - 测试2
|
||||
- user2
|
||||
- pass2
|
||||
- code2
|
||||
- - 测试3
|
||||
- user3
|
||||
- pass3
|
||||
- code3
|
||||
- - 测试4
|
||||
- user4
|
||||
- pass4
|
||||
- code4
|
||||
epic: 项目名称:answer
|
||||
feature: 页面状态
|
||||
story: 状态
|
||||
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.new_case:62 - ddt_title=['查询状态信息', '查询状态信息', '查询状态信息', '查询状态信息']
|
||||
02/28/2025 02:08:06 PM [pytest_result_log] INFO plugin.pytest_runtest_setup:122 - ----------------Start: main.py::TestAPI::test_1_status[查询状态信息0]-----------------
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.test_func:70 - =================================用例开始执行:查询状态信息==================================
|
||||
02/28/2025 02:08:06 PM [commons.exchange] INFO exchange.replace:64 - CaseInfo(title='查询状态信息', request={'method': 'get', 'url': '/answer/api/v1/connector/info', 'headers': {'Host': '119.91.19.171:40065', 'Accept-Language': 'en_US', 'Accept': 'application/json, text/plain, */*', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0', 'Referer': 'http://119.91.19.171:40065/users/login', 'Accept-Encoding': 'gzip, deflate'}}, extract={'code': ['json', '$.code', 0], 'msg': ['json', '$.msg', 0]}, validate={'equals': {'状态码等于200': ['Success.', '${msg}']}}, parametrize=[['title', 'username', 'password', 'code'], ['测试1', 'user1', 'pass1', 'code1'], ['测试2', 'user2', 'pass2', 'code2'], ['测试3', 'user3', 'pass3', 'code3'], ['测试4', 'user4', 'pass4', 'code4']], epic='项目名称:answer', feature='页面状态', story='状态')
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.test_func:74 - 1,正在注入变量...
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.test_func:77 - 2,正在请求接口...
|
||||
02/28/2025 02:08:06 PM [requests.session] INFO session.send:36 - 发送请求>>>>>> 接口地址 = GET http://119.91.19.171:40065/answer/api/v1/connector/info
|
||||
02/28/2025 02:08:06 PM [requests.session] INFO session.send:37 - 发送请求>>>>>> 请求头 = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': 'application/json, text/plain, */*', 'Connection': 'keep-alive', 'Host': '119.91.19.171:40065', 'Accept-Language': 'en_US', 'Referer': 'http://119.91.19.171:40065/users/login'}
|
||||
02/28/2025 02:08:06 PM [requests.session] INFO session.send:38 - 发送请求>>>>>> 请求正文 = None
|
||||
02/28/2025 02:08:06 PM [requests.session] INFO session.send:42 - 接收响应 <<<<<< 状态码 = 200
|
||||
02/28/2025 02:08:06 PM [requests.session] INFO session.send:43 - 接收响应 <<<<<< 响应头 = {'Content-Type': 'application/json; charset=utf-8', 'Date': 'Fri, 28 Feb 2025 06:08:07 GMT', 'Content-Length': '63'}
|
||||
02/28/2025 02:08:06 PM [requests.session] INFO session.send:44 - 接收响应 <<<<<< 响应正文 = {'code': 200, 'reason': 'base.success', 'msg': 'Success.', 'data': []}
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.test_func:80 - 3,正在提取变量...
|
||||
02/28/2025 02:08:06 PM [commons.cases] INFO cases.test_func:86 - 4,正在断言...
|
||||
02/28/2025 02:08:06 PM [commons.exchange] INFO exchange.replace:64 - CaseInfo(title='查询状态信息', request={'method': 'get', 'url': '/answer/api/v1/connector/info', 'headers': {'Host': '119.91.19.171:40065', 'Accept-Language': 'en_US', 'Accept': 'application/json, text/plain, */*', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0', 'Referer': 'http://119.91.19.171:40065/users/login', 'Accept-Encoding': 'gzip, deflate'}}, extract={'code': ['json', '$.code', 0], 'msg': ['json', '$.msg', 0]}, validate={'equals': {'状态码等于200': ['Success.', '${msg}']}}, parametrize=[['title', 'username', 'password', 'code'], ['测试1', 'user1', 'pass1', 'code1'], ['测试2', 'user2', 'pass2', 'code2'], ['测试3', 'user3', 'pass3', 'code3'], ['测试4', 'user4', 'pass4', 'code4']], epic='项目名称:answer', feature='页面状态', story='状态')
|
||||
02/28/2025 02:08:06 PM [pytest_result_log] ERROR plugin.pytest_result_log:190 - test status is FAILED (main.py::TestAPI::test_1_status[查询状态信息0]): TypeError
|
||||
02/28/2025 02:08:06 PM [pytest_result_log] INFO plugin.pytest_runtest_teardown:128 - -----------------End: main.py::TestAPI::test_1_status[查询状态信息0]------------------
|
||||
|
||||
2
main.py
2
main.py
@@ -16,4 +16,4 @@ if __name__ == '__main__':
|
||||
os.system('allure generate temp -o report --clean') # java程序只能借助操作系统执行
|
||||
|
||||
# 3,备份日志
|
||||
shutil.copy2("logs/pytest.log", f"logs/pytest_{now}.log")
|
||||
# shutil.copy2("logs/pytest.log", f"logs/pytest_{now}.log")
|
||||
|
||||
@@ -4,7 +4,7 @@ addopts = -q --show-capture=no
|
||||
|
||||
log_file = logs/pytest.log
|
||||
log_file_level = info
|
||||
log_file_format = '%(asctime)s [%(name)s] %(levelname)s %(module)s.%(funcName)s:%(lineno)d - %(message)s'
|
||||
log_file_date_format = '%m/%d/%Y %I:%M:%S %p'
|
||||
log_file_format = %(asctime)s [%(name)s] %(levelname)s %(module)s.%(funcName)s:%(lineno)d - %(message)s
|
||||
log_file_date_format = %m/%d/%Y %I:%M:%S %p
|
||||
|
||||
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = true
|
||||
42
utils/case_parser.py
Normal file
42
utils/case_parser.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: case_parser
|
||||
@date: 2025/2/27 17:25
|
||||
@desc:
|
||||
"""
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass, asdict, field
|
||||
|
||||
import yaml
|
||||
|
||||
from commons.models import CaseInfo
|
||||
|
||||
|
||||
class CaseParser:
|
||||
@staticmethod
|
||||
def to_yaml(case_data: dict) -> str:
|
||||
return yaml.safe_dump(case_data, allow_unicode=True, sort_keys=False)
|
||||
|
||||
@staticmethod
|
||||
def from_yaml(yaml_str: str) -> CaseInfo:
|
||||
return CaseInfo(**yaml.safe_load(yaml_str))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
with open(r'D:\CNWei\CNW\InterfaceAutoTest\TestCases\answer\test_1_status.yaml', encoding='utf-8') as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
print(data)
|
||||
print(type(data))
|
||||
# print(CaseInfo(**data))
|
||||
case_parser = CaseParser()
|
||||
case_data_ = case_parser.to_yaml(data)
|
||||
# print(case_data_)
|
||||
case_parser.from_yaml(case_data_)
|
||||
# print(type(case_data_))
|
||||
78
utils/case_validator.py
Normal file
78
utils/case_validator.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
|
||||
"""
|
||||
@author: CNWei
|
||||
@Software: PyCharm
|
||||
@contact: t6i888@163.com
|
||||
@file: case_validator
|
||||
@date: 2025/2/27 17:25
|
||||
@desc:
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CaseValidator:
|
||||
VALIDATORS = {}
|
||||
|
||||
@classmethod
|
||||
def register(cls, name: str):
|
||||
def decorator(func):
|
||||
cls.VALIDATORS[name] = func
|
||||
return func
|
||||
|
||||
return decorator
|
||||
|
||||
@classmethod
|
||||
def assert_all(cls, validate: dict):
|
||||
for assert_type, cases in validate.items():
|
||||
print(f"键:{assert_type},值:{cases}")
|
||||
validator = cls.VALIDATORS.get(assert_type)
|
||||
print(f"获取到的断言:{validator}")
|
||||
if not validator:
|
||||
raise KeyError(f"Unsupported validator: {assert_type}")
|
||||
for msg, (a, b) in cases.items():
|
||||
validator(a, b, msg)
|
||||
|
||||
|
||||
@CaseValidator.register('equals')
|
||||
def validate_equals(a, b, msg):
|
||||
logger.info(f"assert {a} == {b}, {msg}执行这段代码")
|
||||
assert a == b, msg
|
||||
|
||||
|
||||
@CaseValidator.register('not_equals')
|
||||
def validate_not_equals(a, b, msg):
|
||||
logger.info(f"assert {a} != {b}, {msg}")
|
||||
assert a != b, msg
|
||||
|
||||
|
||||
@CaseValidator.register('contains')
|
||||
def validate_contains(a, b, msg):
|
||||
logger.info(f"assert {a} in {b}, {msg}")
|
||||
assert a in b, msg
|
||||
|
||||
|
||||
@CaseValidator.register('not_contains')
|
||||
def validate_not_contains(a, b, msg):
|
||||
logger.info(f"assert {a} not in {b}, {msg}")
|
||||
assert a not in b, msg
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mock_case = {
|
||||
"validate": {
|
||||
"equals": {
|
||||
"判断相等": ["Success.", "Success."]
|
||||
},
|
||||
"not_equals": {
|
||||
"判断不相等": ["Success.", "Suc."]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case_validator = CaseValidator()
|
||||
# print(case_validator.VALIDATORS)
|
||||
case_validator.assert_all(mock_case.get("validate"))
|
||||
Reference in New Issue
Block a user