From 1890918312fc6c3cdc24b12db65556914ff7a3f4 Mon Sep 17 00:00:00 2001 From: CNWei Date: Fri, 28 Feb 2025 17:48:20 +0800 Subject: [PATCH] =?UTF-8?q?refactor(models):=20=E4=BC=98=E5=8C=96=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构assert_all - 优化目录结构 --- .gitignore | 6 +-- commons/cases.py | 10 +++-- commons/exchange.py | 6 +-- commons/files.py | 7 +++- commons/funcs.py | 11 ++---- commons/models.py | 48 ++++++++++++----------- commons/settings.py | 6 +-- commons/templates.py | 8 +++- id.yaml | 2 +- logs/pytest.log | 87 ++++++++++++++++++++++++++++++++--------- main.py | 2 +- pytest.ini | 4 +- utils/case_parser.py | 42 ++++++++++++++++++++ utils/case_validator.py | 78 ++++++++++++++++++++++++++++++++++++ 14 files changed, 250 insertions(+), 67 deletions(-) create mode 100644 utils/case_parser.py create mode 100644 utils/case_validator.py diff --git a/.gitignore b/.gitignore index 5119888..29eada9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,6 @@ .venv/ poetry.lock .pytest_cache/ -report -temp -logs \ No newline at end of file +report/ +temp/ +logs/ \ No newline at end of file diff --git a/commons/cases.py b/commons/cases.py index cd83092..d89784f 100644 --- a/commons/cases.py +++ b/commons/cases.py @@ -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) diff --git a/commons/exchange.py b/commons/exchange.py index d2dcefa..0c475cd 100644 --- a/commons/exchange.py +++ b/commons/exchange.py @@ -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) diff --git a/commons/files.py b/commons/files.py index 7639efc..e48e3fa 100644 --- a/commons/files.py +++ b/commons/files.py @@ -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() diff --git a/commons/funcs.py b/commons/funcs.py index 38b7a8c..6f77e6d 100644 --- a/commons/funcs.py +++ b/commons/funcs.py @@ -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()}") diff --git a/commons/models.py b/commons/models.py index 5d7c057..e466b69 100644 --- a/commons/models.py +++ b/commons/models.py @@ -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 = [] diff --git a/commons/settings.py b/commons/settings.py index b28c36c..c6d1883 100644 --- a/commons/settings.py +++ b/commons/settings.py @@ -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" diff --git a/commons/templates.py b/commons/templates.py index d7dd096..d7de0a9 100644 --- a/commons/templates.py +++ b/commons/templates.py @@ -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() diff --git a/id.yaml b/id.yaml index e858b93..521d46b 100644 --- a/id.yaml +++ b/id.yaml @@ -1 +1 @@ -"id":0 \ No newline at end of file +id: 9 diff --git a/logs/pytest.log b/logs/pytest.log index 568e68e..92f4f2f 100644 --- a/logs/pytest.log +++ b/logs/pytest.log @@ -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]------------------ diff --git a/main.py b/main.py index fa96322..6edf32b 100644 --- a/main.py +++ b/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") diff --git a/pytest.ini b/pytest.ini index 74e6858..db1ffae 100644 --- a/pytest.ini +++ b/pytest.ini @@ -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 \ No newline at end of file diff --git a/utils/case_parser.py b/utils/case_parser.py new file mode 100644 index 0000000..a08f8bd --- /dev/null +++ b/utils/case_parser.py @@ -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_)) diff --git a/utils/case_validator.py b/utils/case_validator.py new file mode 100644 index 0000000..7e3f477 --- /dev/null +++ b/utils/case_validator.py @@ -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"))