新增前置处理
This commit is contained in:
parent
d196d72e90
commit
45781e2a18
|
@ -19,7 +19,13 @@ create_task_01:
|
||||||
is_run:
|
is_run:
|
||||||
data:
|
data:
|
||||||
vins: 73401134000000000
|
vins: 73401134000000000
|
||||||
# 请求类型:params 是以url拼接的形式请求,json则传的是json串
|
# 依赖数据库的数据,先从数据库取值再存到缓存里面
|
||||||
|
dependence_case_data:
|
||||||
|
- case_id: self
|
||||||
|
dependent_data:
|
||||||
|
- dependent_type: sqlData
|
||||||
|
jsonpath: $.username
|
||||||
|
replace_key: $.data.mobile
|
||||||
assert:
|
assert:
|
||||||
status:
|
status:
|
||||||
jsonpath: $.status
|
jsonpath: $.status
|
||||||
|
@ -32,7 +38,14 @@ create_task_01:
|
||||||
type: ==
|
type: ==
|
||||||
value: "success"
|
value: "success"
|
||||||
AssertType:
|
AssertType:
|
||||||
# 断言接口返回的username
|
# 断言sql的时候,AssertType 的值需要填写成 SQL AssertType: SQL
|
||||||
sql:
|
sql:
|
||||||
|
- select * from test_goods where shop_id = 515
|
||||||
|
#前置处理,从数据库取值在请求接口
|
||||||
|
setup_sql:
|
||||||
|
- SELECT * FROM test_obp_user.user_biz_info where user_id = '300000405'
|
||||||
|
#后置处理,从数据库删除
|
||||||
|
teardown_sql: delete * from xxx - delete * from xxx
|
||||||
|
#后置处理,从业务逻辑闭环
|
||||||
teardown:
|
teardown:
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
from config.settings import ConfigHandler
|
from config.settings import ConfigHandler
|
||||||
import os
|
import os
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from tools.exceptions import ValueNotFoundError
|
||||||
|
|
||||||
class Cache:
|
class Cache:
|
||||||
""" 设置、读取缓存 """
|
""" 设置、读取缓存 """
|
||||||
|
@ -62,6 +62,19 @@ class Cache:
|
||||||
os.remove(cache_path + "/" + i)
|
os.remove(cache_path + "/" + i)
|
||||||
|
|
||||||
|
|
||||||
|
_cache_config = {}
|
||||||
|
class CacheHandler:
|
||||||
|
@staticmethod
|
||||||
|
def get_cache(cache_data):
|
||||||
|
try:
|
||||||
|
return _cache_config[cache_data]
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError(f"{cache_data}的缓存数据未找到,请检查是否将该数据存入缓存中")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update_cache(*, cache_name, value):
|
||||||
|
_cache_config[cache_name] = value
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
a = Cache('ecu_collection_select_id').get_cache()
|
a = Cache('ecu_collection_select_id').get_cache()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
import ast
|
||||||
|
import json
|
||||||
|
from typing import Text, Dict, Union, List
|
||||||
|
from jsonpath import jsonpath
|
||||||
|
from tools.mysql_control import SetUpMySQL
|
||||||
|
from tools.regular_control import regular, cache_regular
|
||||||
|
from tools.log_control import WARNING
|
||||||
|
from tools.models import TestCase, DependentCaseData, DependentData
|
||||||
|
from tools.cache_control import CacheHandler
|
||||||
|
from config.configs import Config
|
||||||
|
|
||||||
|
|
||||||
|
class DependentCase:
|
||||||
|
""" 处理依赖相关的业务 """
|
||||||
|
|
||||||
|
def __init__(self, dependent_yaml_case: TestCase):
|
||||||
|
self.__yaml_case = dependent_yaml_case
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cache(cls, case_id: Text) -> Dict:
|
||||||
|
"""
|
||||||
|
获取缓存用例池中的数据,通过 case_id 提取
|
||||||
|
:param case_id:
|
||||||
|
:return: case_id_01
|
||||||
|
"""
|
||||||
|
_case_data = CacheHandler.get_cache(case_id)
|
||||||
|
return _case_data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def jsonpath_data(
|
||||||
|
cls,
|
||||||
|
obj: Dict,
|
||||||
|
expr: Text) -> list:
|
||||||
|
"""
|
||||||
|
通过jsonpath提取依赖的数据
|
||||||
|
:param obj: 对象信息
|
||||||
|
:param expr: jsonpath 方法
|
||||||
|
:return: 提取到的内容值,返回是个数组
|
||||||
|
|
||||||
|
对象: {"data": applyID} --> jsonpath提取方法: $.data.data.[0].applyId
|
||||||
|
"""
|
||||||
|
|
||||||
|
_jsonpath_data = jsonpath(obj, expr)
|
||||||
|
# 判断是否正常提取到数据,如未提取到,则抛异常
|
||||||
|
if _jsonpath_data is False:
|
||||||
|
raise ValueError(
|
||||||
|
f"jsonpath提取失败!\n 提取的数据: {obj} \n jsonpath规则: {expr}"
|
||||||
|
)
|
||||||
|
return _jsonpath_data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_cache_value(cls, dependent_data: "DependentData") -> Union[Text, None]:
|
||||||
|
"""
|
||||||
|
获取依赖中是否需要将数据存入缓存中
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return dependent_data.set_cache
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def replace_key(cls, dependent_data: "DependentData"):
|
||||||
|
""" 获取需要替换的内容 """
|
||||||
|
try:
|
||||||
|
_replace_key = dependent_data.replace_key
|
||||||
|
return _replace_key
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def url_replace(
|
||||||
|
self,
|
||||||
|
replace_key: Text,
|
||||||
|
jsonpath_dates: Dict,
|
||||||
|
jsonpath_data: list) -> None:
|
||||||
|
"""
|
||||||
|
url中的动态参数替换
|
||||||
|
# 如: 一般有些接口的参数在url中,并且没有参数名称, /api/v1/work/spu/approval/spuApplyDetails/{id}
|
||||||
|
# 那么可以使用如下方式编写用例, 可以使用 $url_params{}替换,
|
||||||
|
# 如/api/v1/work/spu/approval/spuApplyDetails/$url_params{id}
|
||||||
|
:param jsonpath_data: jsonpath 解析出来的数据值
|
||||||
|
:param replace_key: 用例中需要替换数据的 replace_key
|
||||||
|
:param jsonpath_dates: jsonpath 存放的数据值
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
if "$url_param" in replace_key:
|
||||||
|
_url = self.__yaml_case.url.replace(replace_key, str(jsonpath_data[0]))
|
||||||
|
jsonpath_dates['$.url'] = _url
|
||||||
|
else:
|
||||||
|
jsonpath_dates[replace_key] = jsonpath_data[0]
|
||||||
|
|
||||||
|
def _dependent_type_for_sql(
|
||||||
|
self,
|
||||||
|
setup_sql: List,
|
||||||
|
dependence_case_data: "DependentCaseData",
|
||||||
|
jsonpath_dates: Dict) -> None:
|
||||||
|
"""
|
||||||
|
判断依赖类型为 sql,程序中的依赖参数从 数据库中提取数据
|
||||||
|
@param setup_sql: 前置sql语句
|
||||||
|
@param dependence_case_data: 依赖的数据
|
||||||
|
@param jsonpath_dates: 依赖相关的用例数据
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
# 判断依赖数据类型,依赖 sql中的数据
|
||||||
|
if setup_sql is not None:
|
||||||
|
if Config.mysql_db.switch:
|
||||||
|
setup_sql = ast.literal_eval(cache_regular(str(setup_sql)))
|
||||||
|
sql_data = SetUpMySQL().setup_sql_data(sql=setup_sql)
|
||||||
|
dependent_data = dependence_case_data.dependent_data
|
||||||
|
for i in dependent_data:
|
||||||
|
_jsonpath = i.jsonpath
|
||||||
|
jsonpath_data = self.jsonpath_data(obj=sql_data, expr=_jsonpath)
|
||||||
|
_set_value = self.set_cache_value(i)
|
||||||
|
_replace_key = self.replace_key(i)
|
||||||
|
if _set_value is not None:
|
||||||
|
CacheHandler.update_cache(cache_name=_set_value, value=jsonpath_data[0])
|
||||||
|
# Cache(_set_value).set_caches(jsonpath_data[0])
|
||||||
|
if _replace_key is not None:
|
||||||
|
jsonpath_dates[_replace_key] = jsonpath_data[0]
|
||||||
|
self.url_replace(
|
||||||
|
replace_key=_replace_key,
|
||||||
|
jsonpath_dates=jsonpath_dates,
|
||||||
|
jsonpath_data=jsonpath_data,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
WARNING.logger.warning("检查到数据库开关为关闭状态,请确认配置")
|
||||||
|
|
||||||
|
|
||||||
|
def is_dependent(self) -> Union[Dict, bool]:
|
||||||
|
"""
|
||||||
|
判断是否有数据依赖
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 获取用例中的dependent_type值,判断该用例是否需要执行依赖
|
||||||
|
_dependent_type = self.__yaml_case.dependence_case
|
||||||
|
# 获取依赖用例数据
|
||||||
|
_dependence_case_dates = self.__yaml_case.dependence_case_data
|
||||||
|
_setup_sql = self.__yaml_case.setup_sql
|
||||||
|
# 判断是否有依赖
|
||||||
|
if _dependent_type is True:
|
||||||
|
# 读取依赖相关的用例数据
|
||||||
|
jsonpath_dates = {}
|
||||||
|
# 循环所有需要依赖的数据
|
||||||
|
try:
|
||||||
|
for dependence_case_data in _dependence_case_dates:
|
||||||
|
_case_id = dependence_case_data.case_id
|
||||||
|
# 判断依赖数据为sql,case_id需要写成self,否则程序中无法获取case_id
|
||||||
|
if _case_id == 'self':
|
||||||
|
self._dependent_type_for_sql(
|
||||||
|
setup_sql=_setup_sql,
|
||||||
|
dependence_case_data=dependence_case_data,
|
||||||
|
jsonpath_dates=jsonpath_dates)
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"依赖的dependent_type不正确,只支持request、response、sql依赖\n"
|
||||||
|
)
|
||||||
|
return jsonpath_dates
|
||||||
|
except TypeError as exc:
|
||||||
|
raise ValueError(
|
||||||
|
"dependence_case_data下的所有内容均不能为空!"
|
||||||
|
"请检查相关数据是否填写,如已填写,请检查缩进问题"
|
||||||
|
) from exc
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
import types
|
||||||
|
from enum import Enum, unique
|
||||||
|
from typing import Text, Dict, Callable, Union, Optional, List, Any
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationType(Enum):
|
||||||
|
""" 自动化通知方式 """
|
||||||
|
DEFAULT = 0
|
||||||
|
DING_TALK = 1
|
||||||
|
WECHAT = 2
|
||||||
|
EMAIL = 3
|
||||||
|
FEI_SHU = 4
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TestMetrics:
|
||||||
|
""" 用例执行数据 """
|
||||||
|
passed: int
|
||||||
|
failed: int
|
||||||
|
broken: int
|
||||||
|
skipped: int
|
||||||
|
total: int
|
||||||
|
pass_rate: float
|
||||||
|
time: Text
|
||||||
|
|
||||||
|
|
||||||
|
class RequestType(Enum):
|
||||||
|
"""
|
||||||
|
request请求发送,请求参数的数据类型
|
||||||
|
"""
|
||||||
|
JSON = "JSON"
|
||||||
|
PARAMS = "PARAMS"
|
||||||
|
DATA = "DATA"
|
||||||
|
FILE = 'FILE'
|
||||||
|
EXPORT = "EXPORT"
|
||||||
|
NONE = "NONE"
|
||||||
|
|
||||||
|
|
||||||
|
def load_module_functions(module) -> Dict[Text, Callable]:
|
||||||
|
""" 获取 module中方法的名称和所在的内存地址 """
|
||||||
|
module_functions = {}
|
||||||
|
|
||||||
|
for name, item in vars(module).items():
|
||||||
|
if isinstance(item, types.FunctionType):
|
||||||
|
module_functions[name] = item
|
||||||
|
return module_functions
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class DependentType(Enum):
|
||||||
|
"""
|
||||||
|
数据依赖相关枚举
|
||||||
|
"""
|
||||||
|
RESPONSE = 'response'
|
||||||
|
REQUEST = 'request'
|
||||||
|
SQL_DATA = 'sqlData'
|
||||||
|
CACHE = "cache"
|
||||||
|
|
||||||
|
|
||||||
|
class Assert(BaseModel):
|
||||||
|
jsonpath: Text
|
||||||
|
type: Text
|
||||||
|
value: Any
|
||||||
|
AssertType: Union[None, Text] = None
|
||||||
|
|
||||||
|
|
||||||
|
class DependentData(BaseModel):
|
||||||
|
dependent_type: Text
|
||||||
|
jsonpath: Text
|
||||||
|
set_cache: Optional[Text]
|
||||||
|
replace_key: Optional[Text]
|
||||||
|
|
||||||
|
|
||||||
|
class DependentCaseData(BaseModel):
|
||||||
|
case_id: Text
|
||||||
|
# dependent_data: List[DependentData]
|
||||||
|
dependent_data: Union[None, List[DependentData]] = None
|
||||||
|
|
||||||
|
|
||||||
|
class ParamPrepare(BaseModel):
|
||||||
|
dependent_type: Text
|
||||||
|
jsonpath: Text
|
||||||
|
set_cache: Text
|
||||||
|
|
||||||
|
|
||||||
|
class SendRequest(BaseModel):
|
||||||
|
dependent_type: Text
|
||||||
|
jsonpath: Optional[Text]
|
||||||
|
cache_data: Optional[Text]
|
||||||
|
set_cache: Optional[Text]
|
||||||
|
replace_key: Optional[Text]
|
||||||
|
|
||||||
|
|
||||||
|
class TearDown(BaseModel):
|
||||||
|
case_id: Text
|
||||||
|
param_prepare: Optional[List["ParamPrepare"]]
|
||||||
|
send_request: Optional[List["SendRequest"]]
|
||||||
|
|
||||||
|
|
||||||
|
class CurrentRequestSetCache(BaseModel):
|
||||||
|
type: Text
|
||||||
|
jsonpath: Text
|
||||||
|
name: Text
|
||||||
|
|
||||||
|
|
||||||
|
class TestCase(BaseModel):
|
||||||
|
url: Text
|
||||||
|
method: Text
|
||||||
|
detail: Text
|
||||||
|
# assert_data: Union[Dict, Text] = Field(..., alias="assert")
|
||||||
|
assert_data: Union[Dict, Text]
|
||||||
|
headers: Union[None, Dict, Text] = {}
|
||||||
|
requestType: Text
|
||||||
|
is_run: Union[None, bool, Text] = None
|
||||||
|
data: Any = None
|
||||||
|
dependence_case: Union[None, bool] = False
|
||||||
|
dependence_case_data: Optional[Union[None, List["DependentCaseData"], Text]] = None
|
||||||
|
sql: List = None
|
||||||
|
setup_sql: List = None
|
||||||
|
status_code: Optional[int] = None
|
||||||
|
teardown_sql: Optional[List] = None
|
||||||
|
teardown: Union[List["TearDown"], None] = None
|
||||||
|
current_request_set_cache: Optional[List["CurrentRequestSetCache"]]
|
||||||
|
sleep: Optional[Union[int, float]]
|
||||||
|
|
||||||
|
|
||||||
|
class ResponseData(BaseModel):
|
||||||
|
url: Text
|
||||||
|
is_run: Union[None, bool, Text]
|
||||||
|
detail: Text
|
||||||
|
response_data: Text
|
||||||
|
request_body: Any
|
||||||
|
method: Text
|
||||||
|
sql_data: Dict
|
||||||
|
yaml_data: "TestCase"
|
||||||
|
headers: Dict
|
||||||
|
cookie: Dict
|
||||||
|
assert_data: Dict
|
||||||
|
res_time: Union[int, float]
|
||||||
|
status_code: int
|
||||||
|
teardown: List["TearDown"] = None
|
||||||
|
teardown_sql: Union[None, List]
|
||||||
|
body: Any
|
||||||
|
|
||||||
|
|
||||||
|
class DingTalk(BaseModel):
|
||||||
|
webhook: Union[Text, None]
|
||||||
|
secret: Union[Text, None]
|
||||||
|
|
||||||
|
|
||||||
|
class MySqlDB(BaseModel):
|
||||||
|
switch: bool = False
|
||||||
|
host: Union[Text, None] = None
|
||||||
|
user: Union[Text, None] = None
|
||||||
|
password: Union[Text, None] = None
|
||||||
|
port: Union[int, None] = 3306
|
||||||
|
|
||||||
|
|
||||||
|
class Webhook(BaseModel):
|
||||||
|
webhook: Union[Text, None]
|
||||||
|
|
||||||
|
|
||||||
|
class Email(BaseModel):
|
||||||
|
send_user: Union[Text, None]
|
||||||
|
email_host: Union[Text, None]
|
||||||
|
stamp_key: Union[Text, None]
|
||||||
|
# 收件人
|
||||||
|
send_list: Union[Text, None]
|
||||||
|
|
||||||
|
|
||||||
|
class Config(BaseModel):
|
||||||
|
project_name: Text
|
||||||
|
env: Text
|
||||||
|
tester_name: Text
|
||||||
|
notification_type: int = 0
|
||||||
|
excel_report: bool
|
||||||
|
ding_talk: "DingTalk"
|
||||||
|
mysql_db: "MySqlDB"
|
||||||
|
mirror_source: Text
|
||||||
|
wechat: "Webhook"
|
||||||
|
email: "Email"
|
||||||
|
lark: "Webhook"
|
||||||
|
real_time_update_test_cases: bool = False
|
||||||
|
host: Text
|
||||||
|
app_host: Union[Text, None]
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class AllureAttachmentType(Enum):
|
||||||
|
"""
|
||||||
|
allure 报告的文件类型枚举
|
||||||
|
"""
|
||||||
|
TEXT = "txt"
|
||||||
|
CSV = "csv"
|
||||||
|
TSV = "tsv"
|
||||||
|
URI_LIST = "uri"
|
||||||
|
|
||||||
|
HTML = "html"
|
||||||
|
XML = "xml"
|
||||||
|
JSON = "json"
|
||||||
|
YAML = "yaml"
|
||||||
|
PCAP = "pcap"
|
||||||
|
|
||||||
|
PNG = "png"
|
||||||
|
JPG = "jpg"
|
||||||
|
SVG = "svg"
|
||||||
|
GIF = "gif"
|
||||||
|
BMP = "bmp"
|
||||||
|
TIFF = "tiff"
|
||||||
|
|
||||||
|
MP4 = "mp4"
|
||||||
|
OGG = "ogg"
|
||||||
|
WEBM = "webm"
|
||||||
|
|
||||||
|
PDF = "pdf"
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class AssertMethod(Enum):
|
||||||
|
"""断言类型"""
|
||||||
|
equals = "=="
|
||||||
|
less_than = "lt"
|
||||||
|
less_than_or_equals = "le"
|
||||||
|
greater_than = "gt"
|
||||||
|
greater_than_or_equals = "ge"
|
||||||
|
not_equals = "not_eq"
|
||||||
|
string_equals = "str_eq"
|
||||||
|
length_equals = "len_eq"
|
||||||
|
length_greater_than = "len_gt"
|
||||||
|
length_greater_than_or_equals = 'len_ge'
|
||||||
|
length_less_than = "len_lt"
|
||||||
|
length_less_than_or_equals = 'len_le'
|
||||||
|
contains = "contains"
|
||||||
|
contained_by = 'contained_by'
|
||||||
|
startswith = 'startswith'
|
||||||
|
endswith = 'endswith'
|
|
@ -1,41 +1,41 @@
|
||||||
#!/usr/bin/env python
|
"""
|
||||||
# -*- coding: utf-8 -*-
|
mysql 封装,支持 增、删、改、查
|
||||||
|
"""
|
||||||
|
import ast
|
||||||
import pymysql
|
import datetime
|
||||||
|
import decimal
|
||||||
from warnings import filterwarnings
|
from warnings import filterwarnings
|
||||||
from tools.yaml_control import GetYamlData
|
import pymysql
|
||||||
from tools.log_control import ERROR
|
from typing import List, Union, Text, Dict
|
||||||
from tools.yaml_control import GetCaseData
|
from utils import config
|
||||||
from config.settings import ConfigHandler
|
from utils.logging_tool.log_control import ERROR
|
||||||
from tools.regular_control import sql_regular
|
from utils.read_files_tools.regular_control import sql_regular
|
||||||
|
from utils.read_files_tools.regular_control import cache_regular
|
||||||
|
from utils.other_tools.exceptions import DataAcquisitionFailed, ValueTypeError
|
||||||
|
|
||||||
# 忽略 Mysql 告警信息
|
# 忽略 Mysql 告警信息
|
||||||
filterwarnings("ignore", category=pymysql.Warning)
|
filterwarnings("ignore", category=pymysql.Warning)
|
||||||
|
|
||||||
switch = GetCaseData(ConfigHandler.config_path).get_yaml_data()['MySqlDB']['switch']
|
|
||||||
|
|
||||||
|
class MysqlDB:
|
||||||
class MysqlDB(object):
|
""" mysql 封装 """
|
||||||
if switch:
|
if config.mysql_db.switch:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.config = GetYamlData(ConfigHandler.config_path)
|
|
||||||
self.read_mysql_config = self.config.get_yaml_data()['MySqlDB']
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 建立数据库连接
|
# 建立数据库连接
|
||||||
self.conn = pymysql.connect(
|
self.conn = pymysql.connect(
|
||||||
host=self.read_mysql_config['host'],
|
host=config.mysql_db.host,
|
||||||
user=self.read_mysql_config['user'],
|
user=config.mysql_db.user,
|
||||||
password=self.read_mysql_config['password'],
|
password=config.mysql_db.password,
|
||||||
db=self.read_mysql_config['db']
|
port=config.mysql_db.port
|
||||||
)
|
)
|
||||||
|
|
||||||
# 使用 cursor 方法获取操作游标,得到一个可以执行sql语句,并且操作结果为字典返回的游标
|
# 使用 cursor 方法获取操作游标,得到一个可以执行sql语句,并且操作结果为字典返回的游标
|
||||||
self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
|
self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
|
||||||
except Exception as e:
|
except AttributeError as error:
|
||||||
ERROR.logger.error("数据库连接失败,失败原因{0}".format(e))
|
ERROR.logger.error("数据库连接失败,失败原因 %s", error)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
try:
|
try:
|
||||||
|
@ -43,8 +43,8 @@ class MysqlDB(object):
|
||||||
self.cur.close()
|
self.cur.close()
|
||||||
# 关闭连接
|
# 关闭连接
|
||||||
self.conn.close()
|
self.conn.close()
|
||||||
except Exception as e:
|
except AttributeError as error:
|
||||||
ERROR.logger.error("数据库连接失败,失败原因{0}".format(e))
|
ERROR.logger.error("数据库连接失败,失败原因 %s", error)
|
||||||
|
|
||||||
def query(self, sql, state="all"):
|
def query(self, sql, state="all"):
|
||||||
"""
|
"""
|
||||||
|
@ -59,16 +59,15 @@ class MysqlDB(object):
|
||||||
if state == "all":
|
if state == "all":
|
||||||
# 查询全部
|
# 查询全部
|
||||||
data = self.cur.fetchall()
|
data = self.cur.fetchall()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# 查询单条
|
# 查询单条
|
||||||
data = self.cur.fetchone()
|
data = self.cur.fetchone()
|
||||||
|
|
||||||
return data
|
return data
|
||||||
except Exception as e:
|
except AttributeError as error_data:
|
||||||
ERROR.logger.error("数据库连接失败,失败原因{0}".format(e))
|
ERROR.logger.error("数据库连接失败,失败原因 %s", error_data)
|
||||||
|
raise
|
||||||
|
|
||||||
def execute(self, sql):
|
def execute(self, sql: Text):
|
||||||
"""
|
"""
|
||||||
更新 、 删除、 新增
|
更新 、 删除、 新增
|
||||||
:param sql:
|
:param sql:
|
||||||
|
@ -80,10 +79,59 @@ class MysqlDB(object):
|
||||||
# 提交事务
|
# 提交事务
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
return rows
|
return rows
|
||||||
except Exception as e:
|
except AttributeError as error:
|
||||||
ERROR.logger.error("数据库连接失败,失败原因{0}".format(e))
|
ERROR.logger.error("数据库连接失败,失败原因 %s", error)
|
||||||
# 如果事务异常,则回滚数据
|
# 如果事务异常,则回滚数据
|
||||||
self.conn.rollback()
|
self.conn.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def sql_data_handler(cls, query_data, data):
|
||||||
|
"""
|
||||||
|
处理部分类型sql查询出来的数据格式
|
||||||
|
@param query_data: 查询出来的sql数据
|
||||||
|
@param data: 数据池
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
# 将sql 返回的所有内容全部放入对象中
|
||||||
|
for key, value in query_data.items():
|
||||||
|
if isinstance(value, decimal.Decimal):
|
||||||
|
data[key] = float(value)
|
||||||
|
elif isinstance(value, datetime.datetime):
|
||||||
|
data[key] = str(value)
|
||||||
|
else:
|
||||||
|
data[key] = value
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class SetUpMySQL(MysqlDB):
|
||||||
|
""" 处理前置sql """
|
||||||
|
|
||||||
|
def setup_sql_data(self, sql: Union[List, None]) -> Dict:
|
||||||
|
"""
|
||||||
|
处理前置请求sql
|
||||||
|
:param sql:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
sql = ast.literal_eval(cache_regular(str(sql)))
|
||||||
|
try:
|
||||||
|
data = {}
|
||||||
|
if sql is not None:
|
||||||
|
for i in sql:
|
||||||
|
# 判断断言类型为查询类型的时候,
|
||||||
|
if i[0:6].upper() == 'SELECT':
|
||||||
|
sql_date = self.query(sql=i)[0]
|
||||||
|
for key, value in sql_date.items():
|
||||||
|
data[key] = value
|
||||||
|
else:
|
||||||
|
self.execute(sql=i)
|
||||||
|
return data
|
||||||
|
except IndexError as exc:
|
||||||
|
raise DataAcquisitionFailed("sql 数据查询失败,请检查setup_sql语句是否正确") from exc
|
||||||
|
|
||||||
|
|
||||||
|
class AssertExecution(MysqlDB):
|
||||||
|
""" 处理断言sql数据 """
|
||||||
|
|
||||||
def assert_execution(self, sql: list, resp) -> dict:
|
def assert_execution(self, sql: list, resp) -> dict:
|
||||||
"""
|
"""
|
||||||
|
@ -96,27 +144,28 @@ class MysqlDB(object):
|
||||||
if isinstance(sql, list):
|
if isinstance(sql, list):
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
if 'UPDATE' and 'update' and 'DELETE' and 'delete' and 'INSERT' and 'insert' in sql:
|
_sql_type = ['UPDATE', 'update', 'DELETE', 'delete', 'INSERT', 'insert']
|
||||||
raise ValueError("断言的 sql 必须是查询的 sql")
|
if any(i in sql for i in _sql_type) is False:
|
||||||
else:
|
|
||||||
for i in sql:
|
for i in sql:
|
||||||
# 判断sql中是否有正则,如果有则通过jsonpath提取相关的数据
|
# 判断sql中是否有正则,如果有则通过jsonpath提取相关的数据
|
||||||
sql = sql_regular(i, resp)
|
sql = sql_regular(i, resp)
|
||||||
|
if sql is not None:
|
||||||
# for 循环逐条处理断言 sql
|
# for 循环逐条处理断言 sql
|
||||||
query_data = self.query(sql)[0]
|
query_data = self.query(sql)[0]
|
||||||
# 将sql 返回的所有内容全部放入对象中
|
data = self.sql_data_handler(query_data, data)
|
||||||
for key, value in query_data.items():
|
|
||||||
data[key] = value
|
|
||||||
|
|
||||||
return data
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("断言的查询sql需要是list类型")
|
raise DataAcquisitionFailed(f"该条sql未查询出任何数据, {sql}")
|
||||||
except Exception as e:
|
else:
|
||||||
ERROR.logger.error("数据库连接失败,失败原因{0}".format(e))
|
raise DataAcquisitionFailed("断言的 sql 必须是查询的 sql")
|
||||||
raise
|
else:
|
||||||
|
raise ValueTypeError("sql数据类型不正确,接受的是list")
|
||||||
|
return data
|
||||||
|
except Exception as error_data:
|
||||||
|
ERROR.logger.error("数据库连接失败,失败原因 %s", error_data)
|
||||||
|
raise error_data
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
mysql_db = MysqlDB()
|
a = MysqlDB()
|
||||||
a = mysql_db.assert_execution(sql=[""], resp={"code": 237, "value": 1})
|
b = a.query(sql="select * from `test_obp_configure`.lottery_prize where activity_id = 3")
|
||||||
print(a)
|
print(b)
|
Loading…
Reference in New Issue