Python+requests+Pytest+logging+allure+pymysql框架详解
一、框架目录结构
- 1)tools目录用来放公共方法存储,如发送接口以及读取测试数据的方法,响应断言 数据库断言 前置sql等方法;
- 2)datas目录用例存储接口用例的测试数据,我是用excel来存储的数据,文件数据 图片数据等;
- 3)testcases目录用来存放测试用例,一个python文件对应一个接口模块的测试用例,不同接口分别别多个不同的python文件;
- 4)outputs里有reports和logs,report目录用来存放测试报告,报告是HTML格式的;logs是存放框架日志的;
- 5)run.py是用来执行所有接口用例的入口文件;
二、框架结构代码图解
三、各文件内容详解
tools扩展封装类详解
handle_path.py :文件路径处理
from pathlib import Path log_path = Path(__file__).absolute().parent.parent/"outputs"/"logs"/"mytest.log" # excel表格的路径处理 exc_path = Path(__file__).absolute().parent.parent /"datas" / "testcase_mall.xlsx" # 上传文件 路径 pic_path = Path(__file__).absolute().parent.parent /"datas"
handle_excel.py:读取excel文件内容
from pathlib import Path from openpyxl import load_workbook def read_data(exc_path,sheetname): """ 这是读取excel表格函数 :param exc_path: 用例文件的路径 :param sheetname: 用例表单的名字 :return: """ wb = load_workbook(exc_path) sh = wb[sheetname] cases = list(sh.values) # 所有的用例的列表 [(第一行-title),(第二行用例),(),()] title = cases[0] # 得到标题行 list_case = [] for case in cases[1:]: data = dict(zip(title,case)) # 第一条用例的字典 list_case.append(data) # 每一条用例追加到列表里。 return list_case if __name__ == '__main__': exc_path = Path(__file__).absolute().parent.parent /"datas" / "testcase_mall.xlsx" print(read_data(exc_path, "登录"))
envi_data.py:存储环境变量
# 这个类就是为了存储环境变量 实现环境变量的共享的 class EnviData: pass
handle_replace.py
检查excel读取的内容是否需要替换变量,
需要替换变量,先提取需要替换的变量名,
再查通过需要替换的变量名在环境变量中查询对应的值
替换变量的值并返回。
""" 1、def封装 2、参数化 3、返回值: 最终要拿到替换后的字符串 --- 头部 参数 要用于发送接口测试的 4、加上日志: 但凡你想确认数据结果的地方 都可以加上日志 5、因为有些接口不需要做数据提取,所以判空处理: 6、异常捕获: 因为有可能环境变量里没有这个属性名 和属性值 """ import re import allure from loguru import logger from tools.envi_data import EnviData from tools.handle_generate import GenData @allure.step("替换占位符变量") def replace_mark(str_data): while True: if str_data is None: return result = re.search("#(.*?)#",str_data) if result is None: # 如果没有占位符 就是None 跳出循环 break mark = result.group() # 结果是 #prodId# --要被替换的子字符串| #gen_unregister_phone()# logger.info(f"要被替换的子字符串:{ mark}") if "()" in mark: fun_name = result.group(1) # 第一个分组的值 结果是 gen_unregister_phone() logger.info(f"要提取环境变量的函数名:{ fun_name}") # 通过eval拖引号之后,不可以直接GenData().gen_unregister_name(),要导包 gen_data = eval(f'GenData().{ fun_name}') # 接口函数的返回值结果-生成的数据 logger.info(f"生成的随机的数据是:{ gen_data}") # 1、存数据到环境变量里 -- 类属性的名字 函数名去掉() var_name = fun_name.strip("()") # 结果是 gen_unregister_phone setattr(EnviData,var_name,gen_data) # 属性名:gen_unregister_phone 属性值: gen_data logger.info(f"环境变量的属性值:{ EnviData.__dict__}") # 2、完成第一条的参数的替换 用刚刚生成的数据替换 str_data = str_data.replace(mark,str(gen_data)) logger.info(f"替换完成后的字符串是:{ str_data}") else: var_name = result.group(1) # 第一个分组的值 结果是 prodId logger.info(f"要提取环境变量的属性名:{ var_name}") try: var_value = getattr(EnviData,var_name) # 结果 : 7717--int类型 except AttributeError as e: logger.error(f"环境变量里不存在这个属性:{ var_name}") raise e logger.info(f"要提取环境变量的属性值:{ var_value}") str_data = str_data.replac
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...