Commit fb58c4f7 by xcn

接口自动化

parent e4c840bd
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: __init__.py
# Author: xxxxxxx
# Datetime: 2024/1/2 14:08
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: __init__.py
# Author: xxxxxxx
# Datetime: 2024/1/4 19:11
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
import os.path
from APIAutoTest_v2_my.common.log import log
# 设定日志路径
log_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),"report/log/bpm.log")
# 创建日志对象
my_logger = log(log_path)
# 设置日志装饰器
def log_decorator(func):
def inner(*args, **kwargs):
try:
my_logger.info("方法或函数的名称为:"+str(func.__name__)+"方法或函数的功能为:"+str(func.__doc__))
value = func(*args,**kwargs)
except Exception as e:
my_logger.error('方法或函数的名称为:'+str(func.__name__)+"报错为:"+str(e))
else:
return value
return inner
\ No newline at end of file
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: db.py
# Author: xxxxxxx
# Datetime: 2024/1/3 18:31
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
'''
数据库处理文件:
1. 链接数据库
2. 执行sql语句
(1)删除语句
(2)查询语句
3. 关闭数据库
'''
import pymysql
from APIAutoTest_v2_my.common.read_ini import ReadIni
class DB:
def __init__(self):
# 创建ReadIni对象
read_ini = ReadIni()
# 初始化对象连接数据库
try:
self.conn = pymysql.connect(
host=read_ini.get_sql_connect_message('host'),
port=int(read_ini.get_sql_connect_message('port')),
user=read_ini.get_sql_connect_message('user'),
password=read_ini.get_sql_connect_message('pwd'),
database=read_ini.get_sql_connect_message('database'),
charset='utf8'
)
except:
raise pymysql.Error('数据库连接出错!')
else:
# 获取数据库的游标
self.cursor = self.conn.cursor()
# 关闭数据库的方法
def close(self):
# 关闭游标
self.cursor.close()
# 关闭数据库
self.conn.close()
# 执行删除语句
def delete(self, sql_sentence):
# 判断sql语句是否以delete开头
if sql_sentence.strip().lower().startswith('delete'):
try:
# 使用游标对象execute方法执行sql语句
self.cursor.execute(sql_sentence)
# 使用链接对象commit提交
self.conn.commit()
except:
raise ValueError('sql语句错误')
else:
raise ValueError('sql语句错误')
# 执行查询语句
def select(self, sql_sentence):
# 判断sql语句是否以select开头
if sql_sentence.strip().lower().startswith('select'):
try:
# 使用游标对象execute方法执行sql语句
self.cursor.execute(sql_sentence)
# 获取执行后的结果
select_result = self.cursor.fetchall()
# 判断查询的结果是否为空
# 不为空就返回第一个数据的ID
if select_result:
return select_result[0][0]
except:
raise ValueError('sql语句错误!')
else:
raise ValueError('sql语句错误!')
if __name__ == '__main__':
db = DB()
str2 = "seleCT ID_,DEM_NAME_ FROM uc_demension limit 1"
print(db.select(str2))
\ No newline at end of file
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: log.py
# Author: xxxxxxx
# Datetime: 2024/1/4 18:48
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
import logging
# 日志功能
def log(filename):
# 获取日志对象
my_logger = logging.getLogger()
# 创建了一个日志文件
handler = logging.FileHandler(filename,mode='a',encoding='utf-8')
# 定义日志的格式
formatter = logging.Formatter('%(levelname)s--%(asctime)s--%(message)s')
'''
%(levelname)s:代表日志消息级别
%(asctime)s:代表日志消息的时间戳
%(message)s:代表日志消息的内容
'''
# 将上面日志的定义的格式设置为日志格式
handler.setFormatter(formatter)
# 将上面创建的日志文件添加为日志
my_logger.addHandler(handler)
# 将日志级别设定为INFO
my_logger.level = logging.INFO
'''
这段代码将名为my_logger的Logger对象的日志级别设置为logging.INFO。在Python的logging模块中,日志级别用于表示日志消息的重要程度,不同的级别包括DEBUG、INFO、WARNING、ERROR、CRITICAL等。通过将Logger对象的级别设置为特定的级别,可以控制记录在日志中的消息的级别,比如只记录INFO级别及以上的消息。
在这个例子中,将my_logger的级别设置为logging.INFO表示只记录INFO级别及以上的日志消息,而低于INFO级别的消息(如DEBUG)将不会被记录。这样可以灵活地控制日志输出的详细程度,以便在不同环境下进行调试和监控。
'''
return my_logger
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: read_excel.py
# Author: xxxxxxx
# Datetime: 2024/1/3 14:38
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
'''读取excel并将得到的数据组成一个列表返回'''
import openpyxl
from APIAutoTest_v2_my.common.read_ini import ReadIni
from APIAutoTest_v2_my.common.read_json import read_json
class ReadExcel:
def __init__(self,excel_path=None, table_name=None, case_data_path=None, expect_data_path=None, sql_data_path=None):
if not(excel_path and table_name):
# 通过ini文件获取文件路径
self.ini = ReadIni()
# 获取excel文件路径
excel_path_self = self.ini.get_file_path('excel')
#
wb = openpyxl.load_workbook(excel_path_self)
# 获取工作表名称
table_name_self = self.ini.get_table_name('name')
self.ws = wb[table_name_self]
else:
# 打开工作表
self.wb = openpyxl.load_workbook(excel_path)
# 获取工作表
self.ws = self.wb[table_name]
if not(case_data_path and expect_data_path and sql_data_path):
# 获取用例数据文件路径
case_data_path = self.ini.get_file_path('case')
# 获取期望数据文件路径
expect_data_path = self.ini.get_file_path('expect')
# 获取sql数据文件路径
sql_data_path = self.ini.get_file_path('sql')
# 获取json数据
self.case_data = read_json(case_data_path)
self.expect_data = read_json(expect_data_path)
self.sql_data = read_json(sql_data_path)
# 根据行号列号读取格子数据,并将读取的数据返回出来,注意要做空行处理
def __get_cell_value(self, column: str, row: int):
try:
# 获取值
cell_value = self.ws[column + str(row)].value
except:
raise ValueError('传入的行号和列号错误')
else:
if cell_value is None:
return None
elif cell_value.strip():
return cell_value.strip()
# 根据行号获取模块名称
def module_name(self, row):
return self.__get_cell_value('B', row)
# 根据行号获取接口名称
def api_name(self, row):
return self.__get_cell_value('C', row)
# 根据行号获取请求路径
def request_url(self, row):
# 获取域名
bpm_host = self.ini.get_host('bpm_host')
if self.__get_cell_value('G', row):
return bpm_host + self.__get_cell_value('G', row)
# 根据行号获取请求方法
def request_method(self, row):
return self.__get_cell_value('F', row)
# 根据行号获取媒体类型
def mime(self, row):
mime = self.__get_cell_value('H', row)
if mime:
return mime.lower()
# 根据行号获取用例数据
def get_case_data(self, row):
# 获取用例数据名称
case_data_name = self.__get_cell_value('I', row)
# 如果存在获取用例数据
if case_data_name:
# 获取模块名称
module_name = self.module_name(row)
# 获取接口名称
api_name = self.api_name(row)
return self.case_data[module_name][api_name][case_data_name]
# 根据行号获取期望数据
def get_expect_data(self, row):
# 获取用例数据名称
case_expect_name = self.__get_cell_value('J', row)
# 如果存在就获取期望数据,如果不存在则不获取
if case_expect_name:
# 获取模块名称
module_name = self.module_name(row)
# 获取接口名称
api_name = self.api_name(row)
return self.expect_data[module_name][api_name][case_expect_name]
# 根据行号获取sql语句类型
def get_sql_type(self, row):
sql_type = self.__get_cell_value('K', row)
if sql_type:
return sql_type.lower()
# 根据行号获取sql语句
def get_sql_sentence(self, row):
# 获取模块名称
module_name = self.module_name(row)
# 获取接口名称
api_name = self.api_name(row)
# 获取用例数据名称
sql_data_name = self.__get_cell_value('L', row)
# 如果存在就获取期望数据,如果不存在则不获取
if sql_data_name:
return self.sql_data[module_name][api_name][sql_data_name]
# 根据行号获取更新的key
def get_key(self, row):
return self.__get_cell_value('M', row)
# 将excel表中的数据组成一个二位列表返回
def get_data(self):
data_list = []
for row in range(2, self.ws.max_row + 1):
# 获取模块名称
module_name = self.module_name(row)
# 获取api接口名称
api_name = self.api_name(row)
# 获取请求路径
request_url = self.request_url(row)
# 获取请求方法
request_method = self.request_method(row)
# 获取媒体类型
request_mime = self.mime(row)
# 获取用例数据
case_data = self.get_case_data(row)
# 获取期望用例数据
except_data = self.get_expect_data(row)
# 获取sql语句类型
sql_type = self.get_sql_type(row)
# 获取sql语句
sql_sentence = self.get_sql_sentence(row)
# 获取跟新的key
key = self.get_key(row)
# 将上面的数据都放入一个数组当中国
row_list = [request_url, request_method, request_mime, case_data, except_data, sql_type,sql_sentence, key]
# 判断一下有没有超过5个的none,
if not row_list.count(None) > 5:
data_list.append(row_list)
return data_list
if __name__ == '__main__':
read_excel = ReadExcel()
print(read_excel.get_data())
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: read_ini.py
# Author: xxxxxxx
# Datetime: 2024/1/2 14:25
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
import configparser
import os.path
from APIAutoTest_v2_my.common import log_decorator
class ReadIni:
@log_decorator
def __init__(self):
# 获取data_config的目录路径
self.data_config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data_config')
# 获取config文件的路径
ini_path = os.path.join(self.data_config_path, 'config.ini')
# 创建configparser对象
self.conf = configparser.ConfigParser()
# 读文件
self.conf.read(ini_path, encoding='utf-8')
# 获取配置文件中各种key的方法
# 获取ini文件中文件路径的方法
@log_decorator
def get_file_path(self, key):
try:
filename = os.path.join(self.data_config_path, self.conf.get('file', key))
except:
raise KeyError('传入的文件名称错误!')
else:
return filename
# 获取配置文件中table名称的方法
@log_decorator
def get_table_name(self, key):
try:
table_name = self.conf.get('table', key)
except:
raise KeyError('传入的table节点下key错误!')
else:
return table_name
# 获取配置文件中host的方法
@log_decorator
def get_host(self, key):
try:
host = self.conf.get('host', key)
except:
raise KeyError('传入的host名称错误')
else:
return host
# 获取配置文件中sql的方法
@log_decorator
def get_sql_connect_message(self, key):
try:
sql = self.conf.get('sql', key)
except:
raise KeyError('传入的sql节点下的key错误')
else:
return sql
if __name__ == '__main__':
ini = ReadIni()
print(ini.get_sql_connect_message('database'))
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: read_json.py
# Author: xxxxxxx
# Datetime: 2024/1/3 14:16
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
'''
根据传入的路径读取json文件,并将json文件中的内容转换为对象并返回
'''
import json
import os.path
def read_json(filepath):
# 判断传入的路径是否是文件且以json文件结尾
# 如果是就读取文件内容
if os.path.isfile(filepath) and filepath.endswith('json'):
# 创建文件对象
with open(filepath, mode='r', encoding='utf-8') as file:
# 将文件内容转换为json对象
try:
res = json.loads(file.read())
except:
raise FileExistsError('传入的json文件格式错误!')
else:
return res
# 不是json文件
else:
raise FileNotFoundError('传入的json路径不存在!')
{
"认证接口":{
"登录系统":{
"LoginSuccess":{"username":"admin","password":"MTIzNDU2"},
"LoginErrorUsernameIsNone":{"username":"","password":"MTIzNDU2"},
"LoginErrorUsernameIsShort":{"username":"a","password":"MTIzNDU2"},
"LoginErrorUsernameIsLong":{"username":"adminadminadminadminadminadminadminadminadminadmin","password":"MTIzNDU2"},
"LoginErrorUsernameIsSpecial":{"username":"♠♣▣▤▥▦▩◘◙◈","password":"MTIzNDU2"},
"LoginErrorUsernameIsError":{"username":"Admin","password":"MTIzNDU2"},
"LoginErrorPasswordIsNone":{"username":"admin","password":""},
"LoginErrorPasswordIsLong":{"username":"admin","password":"MTIzNDU2MTIzNDU2MTIzNDU2MTIzNDU2MTIzNDU2"},
"LoginErrorPasswordIsShort":{"username":"admin","password":"m"},
"LoginErrorPasswordIsSpecial":{"username":"admin","password":"♠♣▣▤▥▦▩◘◙◈"}
}
},
"维度管理": {
"添加维度": {
"AddDemSuccess": {
"code": "test58_dem_abc",
"description": "测试维度-58",
"isDefault": 0,
"name": "测试维度-58"
}
},
"根据维度编码删除维度": {
"DeleteDemSuccess": {"ids": "需要更新"}
}
},
"组织管理": {
"添加组织": {
"AddOrgSuccess": {
"code": "test_58_org",
"demId": "需要更新",
"exceedLimitNum": 0,
"grade": "",
"limitNum": 0,
"name": "测试组织-58",
"nowNum": 0,
"orderNo": 0,
"parentId": "0"
}
},
"用户加入组织": {
"OrgAddUserSuccess": {"orgCode": "test_58_org", "accounts": "admin,guest"}
},
"保存组织参数": {
"OrgSaveParamSuccess": {"query": {"orgCode": "test_58_org"}, "json": [{"alias": "sz", "value": "999"}]}
},
"删除组织": {
"DeleteOrgSuccess": "test_58_org"
}
},
"用户管理": {
"添加用户": {
"AddUserSuccess": {"id":"","account":"laowang","address":"","email":"","fullname":"laowang","mobile":"","password":"123456","photo":"","sex":"","status":1}
}
}
}
[file]
# 数据配置层中文件的名称
excel=APIAutoTest.xlsx
case=case_data.json
expect=expect_data.json
sql=sql_data.json
[table]
# excel工作表的名称
name=BPM
[host]
# 被测系统的域名
bpm_host=http://120.46.172.186:8080
[sql]
# 数据库链接信息
host=120.46.172.186
port=3306
user=root
pwd=root@2023
database=eipsaas
\ No newline at end of file
{
"认证接口":{
"登录系统":{
"LoginSuccess":{"username":"超级管理员","account":"admin","loginStatus":true},
"LoginErrorUsernameIsNone":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsShort":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsLong":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsSpecial":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsError":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsNone":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsLong":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsShort":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsSpecial":{"state":false,"message":"账号或密码错误"}
},
"刷新token": {
"RefreshTokenSuccess": {"message": "刷新成功"}
}
},
"维度管理": {
"添加维度": {
"AddDemSuccess": {"message": "添加维度成功!"}
},
"根据维度编码删除维度": {
"DeleteDemSuccess": {"message": "删除维度成功!"}
}
},
"组织管理": {
"添加组织": {
"AddOrgSuccess": {"message": "添加组织成功!"}
},
"用户加入组织": {
"OrgAddUserSuccess": {"state":true,"message":"加入成功"}
},
"保存组织参数": {
"OrgSaveParamSuccess": {"state":true,"message":"保存组织参数成功!"}
},
"删除组织": {
"DeleteOrgSuccess": {"state":true,"message":"删除组织成功!"}
}
},
"用户管理": {
"添加用户": {
"AddUserSuccess": {"state":true,"message":"用户添加成功!"}
}
}
}
{
"维度管理": {
"添加维度": {
"AddDemSuccess": " delete from uc_demension WHERE `CODE_`=\"test58_dem_abc\";"
},
"根据维度编码删除维度": {
"DeleteDemSuccess": "select ID_ from uc_demension WHERE `CODE_`=\"test58_dem_abc\";"
}
},
"组织管理": {
"添加组织": {
"AddOrgSuccess": {"delete": "delete from uc_org WHERE `CODE_`=\"test_58_org\";", "select": "select ID_ from uc_demension WHERE `CODE_`=\"test58_dem_abc\";"}
}
},
"用户管理": {
"添加用户": {
"AddUserSuccess": "delete from uc_user WHERE `ACCOUNT_`=\"laowang\";"
}
}
}
{
{
"认证接口":{
"登录系统":{
"LoginSuccess":{"username":"admin","password":"MTIzNDU2"},
"LoginErrorUsernameIsNone":{"username":"","password":"MTIzNDU2"},
"LoginErrorUsernameIsShort":{"username":"a","password":"MTIzNDU2"},
"LoginErrorUsernameIsLong":{"username":"adminadminadminadminadminadminadminadminadminadmin","password":"MTIzNDU2"},
"LoginErrorUsernameIsSpecial":{"username":"♠♣▣▤▥▦▩◘◙◈","password":"MTIzNDU2"},
"LoginErrorUsernameIsError":{"username":"Admin","password":"MTIzNDU2"},
"LoginErrorPasswordIsNone":{"username":"admin","password":""},
"LoginErrorPasswordIsLong":{"username":"admin","password":"MTIzNDU2MTIzNDU2MTIzNDU2MTIzNDU2MTIzNDU2"},
"LoginErrorPasswordIsShort":{"username":"admin","password":"m"},
"LoginErrorPasswordIsSpecial":{"username":"admin","password":"♠♣▣▤▥▦▩◘◙◈"}
}
},
"维度管理": {
"添加维度": {
"AddDemSuccess": {
"code": "test58_dem_abc",
"description": "测试维度-58",
"isDefault": 0,
"name": "测试维度-58"
}
},
"根据维度编码删除维度": {
"DeleteDemSuccess": {"ids": "需要更新"}
}
},
"组织管理": {
"添加组织": {
"AddOrgSuccess": {
"code": "test_58_org",
"demId": "需要更新",
"exceedLimitNum": 0,
"grade": "",
"limitNum": 0,
"name": "测试组织-58",
"nowNum": 0,
"orderNo": 0,
"parentId": "0"
}
},
"用户加入组织": {
"OrgAddUserSuccess": {"orgCode": "test_58_org", "accounts": "admin,guest"}
},
"保存组织参数": {
"OrgSaveParamSuccess": {"query": {"orgCode": "test_58_org"}, "json": [{"alias": "sz", "value": "999"}]}
},
"删除组织": {
"DeleteOrgSuccess": "test_58_org"
}
}
}
{
{
"认证接口":{
"登录系统":{
"LoginSuccess":{"username":"超级管理员","account":"admin","loginStatus":true},
"LoginErrorUsernameIsNone":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsShort":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsLong":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsSpecial":{"state":false,"message":"账号或密码错误"},
"LoginErrorUsernameIsError":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsNone":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsLong":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsShort":{"state":false,"message":"账号或密码错误"},
"LoginErrorPasswordIsSpecial":{"state":false,"message":"账号或密码错误"}
},
"刷新token": {
"RefreshTokenSuccess": {"message": "刷新成功"}
}
},
"维度管理": {
"添加维度": {
"AddDemSuccess": {"message": "添加维度成功!"}
},
"根据维度编码删除维度": {
"DeleteDemSuccess": {"message": "删除维度成功!"}
}
},
"组织管理": {
"添加组织": {
"AddOrgSuccess": {"message": "添加组织成功"}
},
"用户加入组织": {
"OrgAddUserSuccess": {"state":true,"message":"加入成功"}
},
"保存组织参数": {
"OrgSaveParamSuccess": {"state":true,"message":"保存组织参数成功!"}
},
"删除组织": {
"DeleteOrgSuccess": {"state":true,"message":"删除组织成功!"}
}
}
}
{
{
"维度管理": {
"添加维度": {
"AddDemSuccess": " delete from uc_demension WHERE `CODE_`=\"test58_dem_abc\";"
},
"根据维度编码删除维度": {
"DeleteDemSuccess": "select ID_ from uc_demension WHERE `CODE_`=\"test58_dem_abc\";"
}
},
"组织管理": {
"添加组织": {
"AddOrgSuccess": {"delete": "delete from uc_org WHERE `CODE_`=\"test_58_org\";", "select": "select ID_ from uc_demension WHERE `CODE_`=\"test58_dem_abc\";"}
}
}
}
ERROR--2024-01-04 18:27:58--断言失败!用例数据为{'username': 'Admin', 'password': 'MTIzNDU2'}期望数据为{'state': False, 'message': '账号或密码错误'}客户端返回的数据为{"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiLTEiLCJleHAiOjE3MDQ0NTA0NzcsImlhdCI6MTcwNDM2NDA3N30.b3R4Z19cp4XrXKms9E9sk5dxQktUslM8i1SnpJYIL20lVBqdub4TbMZjLoFG6OXVUeslpAftvbiVf28dhR8u3A","username":"超级管理员","account":"admin","userId":"1","expiration":86400,"loginStatus":true,"userAttrs":{"tenantId":"-1"}}
ERROR--2024-01-04 18:27:59--断言失败!用例数据为None期望数据为{'message': '刷新成功'}客户端返回的数据为{"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsInRlbmFudElkIjoiLTEiLCJleHAiOjE3MDQ0NTA0NzgsImlhdCI6MTcwNDM2NDA3OH0.Sc_QLf8QL6lbzgnf_6-GUGjFWok4ZQefYFfVc9dNTGAQ5s8DuuEYqpFI5BzahTewhtZXm4r7Gg5Gtcz3D_sZ-w","username":"","account":"","userId":"","loginStatus":true,"userAttrs":{}}
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: requests_method.py
# Author: xxxxxxx
# Datetime: 2024/1/3 19:17
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
import base64
import requests
from APIAutoTest_v2_my.common.read_ini import ReadIni
class RequestsMethod:
def __init__(self):
# 1. 登录BPM系统配置headers
# 1.1 配置login的请求url
self.read_ini = ReadIni()
login_url = self.read_ini.get_host('bpm_host') + '/auth'
# 1.2 配置登录数据
login_data = {
"password": base64.b64encode('123456'.encode()).decode(),
"username": "admin"
}
# 1.3 创建session对象
self.bpm_session = requests.sessions.Session()
# 1.4 发送登录请求
login_res = self.bpm_session.request(method="post", url=login_url, json=login_data)
# 1.5 获取token并且配置到headers里面
self.bpm_session.headers['Authorization'] = "Bearer " + login_res.json().get('token')
def request_all(self, req_url, req_method, req_mime, req_data):
if req_mime == 'application/x-www-form-urlencoded' or req_mime == 'x-www-form-urlencoded':
return self.bpm_session.request(method=req_method, url=req_url, data=req_data)
elif req_mime == 'application/json' or req_mime == 'json':
return self.bpm_session.request(method=req_method, url=req_url, json=req_data)
elif req_mime == 'multipart/form-data' or req_mime == 'form-data':
return self.bpm_session.request(method=req_method, url=req_url, files=req_data)
elif req_mime == 'query' or req_mime == 'params':
return self.bpm_session.request(method=req_method, url=req_url, params=req_data)
elif req_mime is None:
return self.bpm_session.request(method=req_method, url=req_url)
# 判断媒体类型是否为query|json或者json|query,表示地址栏和请求体同时传参
elif req_mime == 'query|json' or req_mime == "json|query" or req_mime == "json|params" or req_mime == "params|json":
return self.bpm_session.request(method=req_method, url=req_url, params=req_data.get("query"),
json=req_data.get("json"))
# 判断媒体类型是否为text或者为text/plain,使用data关键字传参
elif req_mime == "text" or req_mime == "text/plain":
return self.bpm_session.request(method=req_method, url=req_url, data=req_data)
else:
raise NameError('传入的媒体类型错误,请自行封装!')
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: __init__.py
# Author: xxxxxxx
# Datetime: 2024/1/4 20:07
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: test_58
# FileName: __init__.py
# Author: xxxxxxx
# Datetime: 2024/1/3 17:15
# Description:
#
# ---------------------------------------------------------------------------
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: test_58
# FileName: conftest.py
# Author: xxxxxxx
# Datetime: 2024/1/3 15:23
# Description:
#
# ---------------------------------------------------------------------------
import pytest
from APIAutoTest_v3.common.db import DB
from APIAutoTest_v3.requests_method.requests_method import RequestsMethod
@pytest.fixture(scope="session")
def db_fix():
db = DB()
yield db
db.close()
@pytest.fixture(scope="session")
def req_fix():
req = RequestsMethod()
yield req
\ No newline at end of file
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: test_58
# FileName: test_bpm.py
# Author: xxxxxxx
# Datetime: 2024/1/3 15:20
# Description:
#
# ---------------------------------------------------------------------------
import logging
import os
import pytest
from APIAutoTest_v3.common.read_excel import ReadExcel
laowang_dir_path = os.path.join(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "data_config"), "老王")
excel_path = os.path.join(laowang_dir_path, "laowang.xlsx")
case_data_path = os.path.join(laowang_dir_path, "case_data.json")
expect_data_path = os.path.join(laowang_dir_path, "expect_data.json")
sql_data_path = os.path.join(laowang_dir_path, "sql_data.json")
class TestBPM:
@pytest.mark.parametrize("case_url, case_req, case_mime, case_data, expect_data, sql_type, sql_data, update_key", ReadExcel(excel_path=excel_path,table_name=r'BPM', case_data_path=case_data_path, expect_data_path=expect_data_path, sql_data_path=sql_data_path).get_data())
def test_bpm(self, db_fix, req_fix, case_url, case_req, case_mime, case_data, expect_data, sql_type, sql_data, update_key):
# 判断sql语句的类型是否为delete
if sql_type == "delete":
# 使用DB类对象,调用delete方法执行删除的sql语句
db_fix.delete(sql_data)
# 发送请求
# 判断sql语句类型是否为select
elif sql_type == "select":
# 使用DB类对象,调用select方法执行查询的sql语句,并接收查询的结果
select_result = db_fix.select(sql_data)
# 将查询结果更新到用例数据中
case_data[update_key] = select_result
# 更新之后的用例数据发送给服务器。
# 判断sql语句类型是否为select|delete或者delete|select
elif sql_type == "select|delete" or sql_type == "delete|select":
# 使用DB类对象,调用select方法执行查询sql语句,并接收查询的结果,将查询的结果更新到用例数据中
select_result = db_fix.select(sql_data.get("select"))
case_data[update_key] = select_result
# 使用DB类对象,调用delete方法执行删除sql语句
db_fix.delete(sql_data.get("delete"))
# 使用RequestsMethod对象发送请求
result = req_fix.request_all(req_method=case_req, req_url=case_url, req_mime=case_mime, case_data=case_data)
# 断言
try:
# 获取期望数据的key,期望数据的key对应的值是否和服务器返回的数据key对应的值相等,如果相等断言成功,否则断言失败
for key in expect_data.keys():
assert expect_data[key] == result.json().get(key)
except AssertionError:
logging.error("断言失败,用例数据为:"+str(case_data)+" 期望数据为:"+str(expect_data)+" 服务器返回的数据为:"+result.text)
raise AssertionError("断言失败")
if __name__ == '__main__':
pytest.main()
\ No newline at end of file
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: __init__.py
# Author: xxxxxxx
# Datetime: 2024/1/4 20:07
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: conftest.py
# Author: xxxxxxx
# Datetime: 2024/1/4 14:54
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
import pytest
from APIAutoTest_v2_my.common.db import DB
from APIAutoTest_v2_my.requests_method.requests_method import RequestsMethod
# 自定义固件
@pytest.fixture(scope="session")
def db_fix():
db = DB()
yield db
db.close()
@pytest.fixture(scope="session")
def req_fix():
req = RequestsMethod()
yield req
[pytest]
;;开启日志
;log_cli=true
;;设置日志的级别,如果不设置级别的话,可以设置为NOTSET,如果要设置级别,级别可以有debug,info,warning,error,致命
;log_level=NOTSET
;;设置日志显示的信息格式
;log_format=%(levelname)s--%(asctime)s--%(message)s
;;设置日志中时间显示的格式
;log_date_format=%Y-%m-%d %H:%M:%S
;;每个py文件运行的时候追加的命令
;;addopts=-vs
;
;;设置日志保存的文件
;log_file=../report/log/bpm_test.log
;;设置日志保存在文件中的级别
;log_file_level=ERROR
;;设置日志在文件中的信息格式
;log_file_format=%(levelname)s--%(asctime)s--%(message)s
;;设置文件日志中时间显示的格式
;log_file_date_format=%Y-%m-%d %H:%M:%S
\ No newline at end of file
# -*-coding:utf-8 -*- #
# ---------------------------------------------------------------------------
# ProjectName: pythonProject
# FileName: test_bpm.py
# Author: xxxxxxx
# Datetime: 2024/1/4 14:18
# Description:
# 命名规范:文件名全小写+下划线,类名大驼峰,方法和变量小写+下划线连接,
# 常量大写,变量和常量用名词,方法用动词
# ---------------------------------------------------------------------------
import logging
import pytest
from APIAutoTest_v2_my.common.read_excel import ReadExcel
class TestBPM:
@pytest.mark.parametrize(
"request_url, request_method, request_mime, case_data, except_data, sql_type,sql_sentence, key",
ReadExcel().get_data())
def test_bpm(self, db_fix, req_fix, request_url, request_method, request_mime, case_data, except_data, sql_type,
sql_sentence, key):
# 如果sql_type是delete就执行删除
if sql_type == 'delete':
db_fix.delete(sql_sentence)
elif sql_type == "select":
# 执行DB类对象,使用select方法执行查询的sql语句,并接收查询结果
select_result = db_fix.select(sql_sentence)
# 将查询结果更新到用例数据中
case_data[key] = select_result
elif sql_type == "select|delete" or sql_type == "delete|select":
# 执行删除
db_fix.delete(sql_sentence.get('delete'))
# 执行查询
select_result = db_fix.select(sql_sentence.get('select'))
# 将查询结果更新到用例数据中
case_data[key] = select_result
# 向服务器发送请求
result = req_fix.request_all(req_url=request_url, req_method=request_method, req_mime=request_mime,
req_data=case_data)
# 断言
try:
for key in except_data.keys():
assert except_data[key] == result.json().get(key)
except AssertionError:
logging.error('断言失败!'+'用例数据为'+str(case_data)+'期望数据为'+str(except_data)+'客户端返回的数据为'+str(result.text))
raise AssertionError('断言失败')
if __name__ == '__main__':
pytest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment