优化用例格式,将上传文件代码进行优化封装

This commit is contained in:
zy7y 2020-11-20 23:55:22 +08:00
parent 0192f8aeca
commit 24bcce71e0
11 changed files with 65 additions and 68 deletions

View File

@ -82,11 +82,12 @@
#### 安装教程
1. git clone https://gitee.com/zy7y/apiAutoTest.git
2. 使用pycharm打开项目使用Terminal 输入 python3 -m venv venv 新建虚拟环境
3. 执行pip install -r requirements.txt 安装依赖库
4. 修改config.ymal文件中email文件配置收件人邮箱授权码发件人邮箱
5. 运行/test/test_api.py 文件
1. git clone https://gitee.com/zy7y/apiAutoTest.git / https://github.com/zy7y/apiAutoTest.git
2. 安装Java与allurehttps://www.cnblogs.com/zy7y/p/13403699.html
3. 使用pycharm打开项目使用Terminal 输入 python3 -m venv venv 新建虚拟环境 (可选)
4. 执行pip install -r requirements.txt 安装依赖库若下载超时pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package
5. 修改config.ymal文件中email文件配置收件人邮箱授权码发件人邮箱
6. 运行/test/test_api.py 文件
#### 运行测试前修改
首先确保需要的环境与依赖包无问题之后使用Pycharm打开项目找到`settings`修改为unitest或者其他非pytest具体操作如下
[![B21lr9.md.jpg](https://s1.ax1x.com/2020/11/05/B21lr9.md.jpg)](https://imgchr.com/i/B21lr9)

0
api_server/a.txt Normal file
View File

View File

@ -12,7 +12,7 @@ FastAPI官网 https://fastapi.tiangolo.com/zh/tutorial/request-files/
from typing import List
from fastapi import FastAPI, File, UploadFile, Form
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@ -25,7 +25,7 @@ async def create_upload_file(file_excel: UploadFile = File(...)):
# 保存本地
with open(file_excel.filename, "wb") as f:
f.write(contents)
return {'msg': '操作成功', "filename": file_excel.filename, 'username': username, "meta": {"msg": "ok"}}
return {'msg': '操作成功', "filename": file_excel.filename, "meta": {"msg": "ok"}}
@app.post("/upload_files/", name='上传多个文件')
@ -41,6 +41,6 @@ async def create_upload_files(files: List[UploadFile] = File(...)):
if __name__ == '__main__':
# 启动项目后 访问 http://127.0.0.1:8000/docs 可查看接口文档
# 启动项目后 访问 http://127.0.0.1:8888/docs 可查看接口文档
import uvicorn
uvicorn.run('api:app', reload=True)
uvicorn.run('api:app', reload=True, port=8888)

BIN
api_server/b.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
api_server/c.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -1,5 +1,6 @@
server:
test: http://127.0.0.1:8000
# 本地接口服务
test: http://127.0.0.1:8888/
# https://space.bilibili.com/283273603 演示项目后端服务来自
dev: http://www.ysqorz.top:8888/api/private/v1/

View File

@ -1,35 +1,11 @@
allure-pytest==2.8.17
allure-python-commons==2.8.17
atomicwrites==1.4.0
attrs==20.3.0
certifi==2020.11.8
chardet==3.0.4
click==7.1.2
colorama==0.4.4
fastapi==0.61.2
h11==0.11.0
idna==2.10
importlib-metadata==2.0.0
iniconfig==1.1.1
jsonpath==0.82
loguru==0.5.1
more-itertools==8.6.0
packaging==20.4
pluggy==0.13.1
py==1.9.0
pydantic==1.7.2
pyparsing==2.4.7
pytest==6.0.1
python-multipart==0.0.5
PyYAML==5.3.1
requests==2.24.0
six==1.15.0
starlette==0.13.6
toml==0.10.2
typing-extensions==3.7.4.3
urllib3==1.25.11
uvicorn==0.12.2
win32-setctime==1.0.3
xlrd==1.2.0
yagmail==0.11.224
zipp==3.1.0
uvicorn==0.12.2
fastapi==0.61.2
python-multipart==0.0.5

View File

@ -19,7 +19,7 @@ from tools.read_data import ReadData
# 读取配置文件 对象
rc = ReadConfig()
base_url = rc.read_serve_config('test')
base_url = rc.read_serve_config('dev')
token_reg, res_reg = rc.read_response_reg()
report_data = rc.read_file_path('report_data')
report_generate = rc.read_file_path('report_generate')
@ -49,9 +49,9 @@ class TestApiAuto(object):
# os.system(f'allure serve {report_data}')
logger.warning('报告已生成')
@pytest.mark.parametrize('case_number,case_title,path,is_token,method,parametric_key,file_var,'
@pytest.mark.parametrize('case_number,case_title,path,is_token,method,parametric_key,file_obj,'
'data,expect', data_list)
def test_main(self, case_number, case_title, path, is_token, method, parametric_key, file_var,
def test_main(self, case_number, case_title, path, is_token, method, parametric_key, file_obj,
data, expect):
# 感谢https://www.cnblogs.com/yoyoketang/p/13386145.html提供动态添加标题的实例代码
@ -70,7 +70,7 @@ class TestApiAuto(object):
with allure.step("发送请求取得响应结果的json串"):
allure.attach(json.dumps(base_url + path, ensure_ascii=False, indent=4), "最终请求地址", allure.attachment_type.TEXT)
res = br.api_send(method=method, url=base_url + path, parametric_key=parametric_key, file_obj=file_var,
res = br.api_send(method=method, url=base_url + path, parametric_key=parametric_key, file_obj=file_obj,
data=data, header=header)
allure.attach(json.dumps(res, ensure_ascii=False, indent=4), "实际响应", allure.attachment_type.TEXT)

View File

@ -8,6 +8,8 @@
@time: 2020/7/31
"""
import json
import re
import allure
from jsonpath import jsonpath
@ -28,6 +30,20 @@ def extractor(obj: dict, expr: str = '.') -> object:
return result
def rep_expr(content: str, data: dict, expr: str = '&(.*?)&') -> str:
"""从请求参数的字符串中,使用正则的方法找出合适的字符串内容并进行替换
:param content: 原始的字符串内容
:param data: 在该项目中一般为响应字典从字典取值出来
:param expr: 查找用的正则表达式
return content 替换表达式后的字符串
"""
logger.info(f'替换前内容{content}')
for ctt in re.findall(expr, content):
content = content.replace(f'&{ctt}&', str(extractor(data, ctt)))
logger.info(f'替换后内容{content}')
return content
def convert_json(dict_str: str) -> dict:
"""
:param dict_str: 长得像字典的字符串
@ -40,10 +56,18 @@ def convert_json(dict_str: str) -> dict:
dict_str = dict_str.replace('True', 'true')
elif 'False' in dict_str:
dict_str = dict_str.replace('False', 'false')
return json.loads(dict_str)
dict_str = json.loads(dict_str)
except Exception as e:
logger.error(f'{e} json.loads转字典失败')
return eval(dict_str)
if 'null' in dict_str:
dict_str = dict_str.replace('null', 'None')
elif 'true' in dict_str:
dict_str = dict_str.replace('true', 'True')
elif 'False' in dict_str:
dict_str = dict_str.replace('false', 'False')
dict_str = eval(dict_str)
logger.error(e)
logger.info(f'{dict_str}, {type(dict_str)}')
return dict_str
def allure_title(title: str) -> None:
@ -51,14 +75,14 @@ def allure_title(title: str) -> None:
allure.dynamic.title(title)
def allure_step(step: str, title: object, var: str) -> None:
def allure_step(step: str, var: str) -> None:
"""
:param step: 步骤名称
:param title: 附件标题
:param step: 步骤及附件名称
:param var: 附件内容
"""
with allure.step(step):
allure.attach(json.dumps(var, ensure_ascii=False, indent=4), title, allure.attachment_type.TEXT)
allure.attach(json.dumps(var, ensure_ascii=False, indent=4), step, allure.attachment_type.TEXT)
if __name__ == '__main__':
print(convert_json('["1","2"]'))

View File

@ -7,8 +7,6 @@
@ide: PyCharm
@time: 2020/11/18
"""
import json
import re
from tools import *
@ -28,17 +26,14 @@ class DataProcess:
logger.info(f'添加key: {key}, 对应value: {value}')
@classmethod
def handle_path(cls, path_str: str = '') -> str:
def handle_path(cls, path_str: str) -> str:
"""路径参数处理
:param path_str: 带提取表达式的字符串 /&$.case_005.data.id&/state/&$.case_005.data.create_time&
上述内容表示从响应字典中提取到case_005字典里data字典里id的值假设是500后面&$.case_005.data.create_time& 类似最终提取结果
return /511/state/1605711095
"""
# /&$.case.data.id&/state/&$.case_005.data.create_time&
for i in re.findall('&(.*?)&', path_str):
path_str = path_str.replace(f'&{i}&', str(extractor(cls.response_dict, i)))
logger.info(f'提取出的路径地址: {path_str}')
return path_str
return rep_expr(path_str, cls.response_dict)
@classmethod
def handle_header(cls, is_token: str, response: dict, reg) -> dict:
@ -60,17 +55,15 @@ class DataProcess:
# todo 待完成
if file_obj == '':
return None
file_var = file_obj.split(':')[0]
file_path = file_obj.split(':')[1]
if file_path.startswith('[') and file_path.endswith(']'):
file_path_list = convert_json(file_path)
files = []
for k, v in convert_json(file_obj).items():
# 多文件上传
for file_path in file_path_list:
files.append((file_var, (open(file_path, 'rb'))))
else:
# 单文件上传
files = {file_var: open(file_path, 'rb')}
if isinstance(v, list):
files = []
for path in v:
files.append((k, (open(path, 'rb'))))
else:
# 单文件上传
files = {k: open(v, 'rb')}
return files
@classmethod
@ -81,11 +74,13 @@ class DataProcess:
"""
if variable == '':
return
for i in re.findall('&(.*?)&', variable):
variable = variable.replace(f'&{i}&', str(extractor(cls.response_dict, i)))
variable = convert_json(variable)
data = rep_expr(variable, cls.response_dict)
variable = convert_json(data)
logger.info(f'最终的请求数据如下: {variable}')
return variable
if __name__ == '__main__':
print(convert_json("""{"files":["D:\\apiAutoTest\\data\\case_data - 副本.xls", "D:\\apiAutoTest\\data\\case_data.xlsx"]}"""))