tep0.9.5支持自定义扩展request
tep0.9.5更新了以下内容:
- 自定义request请求日志
- Allure报告添加request描述
- 猴子补丁扩展request
- fixtures支持多层级目录
- FastAPI替代Flask
升级tep到0.9.5版本,使用tep startproject demo
创建项目脚手架,开箱即用以上新功能。
1.自定义request请求日志
tep默认的request请求日志如下所示:
2022-01-22 20:00:26.335 | INFO | tep.client:tep_request_monkey_patch:44 - method:"post" url:"http://127.0.0.1:5000/login" headers:{"Content-Type": "application/json"} json:{"username": "dongfanger", "password": "123456"} status:200 response:{"token":"de2e3ffu29"} elapsed:0.000s
全部都在一行,假如想换行显示,那么可以在utils/http_client.py
文件中修改request_monkey_patch代码:
在测试代码中把from tep.client import request
改成from utils.http_client import request
:
日志就会变成换行显示了:
2022-01-22 20:04:05.379 | INFO | utils.http_client:request_monkey_patch:38 -
method:"post"
headers:{"Content-Type": "application/json"}
json:{"username": "dongfanger", "password": "123456"}
status:200
response:{"token":"de2e3ffu29"}
elapsed:0.000s
2.Allure报告添加request描述
tep的Allure报告默认会有个request & response
:
可以给request添加desc参数,在Allure测试报告中添加描述:
运行以下命令,然后打开Allure测试报告:
pytest -s test_request_monkey_patch.py --tep-reports
3.猴子补丁扩展request
前面的“自定义request请求日志”和“Allure报告添加request描述”已经展示了如何通过猴子补丁扩展日志和扩展报告,您还可以为request扩展更多想要的功能,只需要实现utils/http_client.py
里面的request_monkey_patch函数即可:
#!/usr/bin/python
# encoding=utf-8
import decimal
import json
import time
import allure
from loguru import logger
from tep import client
from tep.client import TepResponse
def request_monkey_patch(req, *args, **kwargs):
start = time.process_time()
desc = ""
if "desc" in kwargs:
desc = kwargs.get("desc")
kwargs.pop("desc")
response = req(*args, **kwargs)
end = time.process_time()
elapsed = str(decimal.Decimal("%.3f" % float(end - start))) + "s"
log4a = "{}\n{}status:{}\nresponse:{}\nelapsed:{}"
try:
kv = ""
for k, v in kwargs.items():
# if not json, str()
try:
v = json.dumps(v, ensure_ascii=False)
except TypeError:
v = str(v)
kv += f"{k}:{v}\n"
if args:
method = f'\nmethod:"{args[0]}" '
else:
method = ""
request_response = log4a.format(method, kv, response.status_code, response.text, elapsed)
logger.info(request_response)
allure.attach(request_response, f'{desc} request & response', allure.attachment_type.TEXT)
except AttributeError:
logger.error("request failed")
except TypeError:
logger.warning(log4a)
return TepResponse(response)
def request(method, url, **kwargs):
client.tep_request_monkey_patch = request_monkey_patch
return client.request(method, url, **kwargs)
4.fixtures支持多层级目录
tep之前一直只能支持fixtures的根目录的fixture_*.py
文件自动导入,现在能支持多层级目录了:
测试代码test_multi_fixture.py
:
#!/usr/bin/python
# encoding=utf-8
def test(fixture_second, fixture_three):
pass
能运行成功。自动导入多层目录的代码实现如下:
# 自动导入fixtures
_fixtures_dir = os.path.join(_project_dir, "fixtures")
for root, _, files in os.walk(_fixtures_dir):
for file in files:
if file.startswith("fixture_") and file.endswith(".py"):
full_path = os.path.join(root, file)
import_path = full_path.replace(_fixtures_dir, "").replace("\\", ".").replace("/", ".").replace(".py", "")
try:
fixture_path = "fixtures" + import_path
exec(f"from {fixture_path} import *")
except:
fixture_path = ".fixtures" + import_path
exec(f"from {fixture_path} import *")
5.FastAPI替代Flask
因为HttpRunner用的FastAPI,所以我也把Flask替换成了FastAPI,在utils/fastapi_mock.py
文件中可以找到代码实现的简易Mock:
#!/usr/bin/python
# encoding=utf-8
import uvicorn
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/login")
async def login(req: Request):
body = await req.json()
if body["username"] == "dongfanger" and body["password"] == "123456":
return {"token": "de2e3ffu29"}
return ""
@app.get("/searchSku")
def search_sku(req: Request):
if req.headers.get("token") == "de2e3ffu29" and req.query_params.get("skuName") == "电子书":
return {"skuId": "222", "price": "2.3"}
return ""
@app.post("/addCart")
async def add_cart(req: Request):
body = await req.json()
if req.headers.get("token") == "de2e3ffu29" and body["skuId"] == "222":
return {"skuId": "222", "price": "2.3", "skuNum": "3", "totalPrice": "6.9"}
return ""
@app.post("/order")
async def order(req: Request):
body = await req.json()
if req.headers.get("token") == "de2e3ffu29" and body["skuId"] == "222":
return {"orderId": "333"}
return ""
@app.post("/pay")
async def pay(req: Request):
body = await req.json()
if req.headers.get("token") == "de2e3ffu29" and body["orderId"] == "333":
return {"success": "true"}
return ""
if __name__ == '__main__':
uvicorn.run("fastapi_mock:app", host="127.0.0.1", port=5000)
最后,感谢@zhangwk02提交的Pull requests,虽然写的代码被我全部优化了,但是提供了很棒的想法和动力。
tep0.9.5支持自定义扩展request的更多相关文章
- 纸壳CMS现已支持自定义扩展字段
简介 纸壳CMS是开源免费的可视化内容管理系统. GitHub https://github.com/SeriaWei/ZKEACMS 自定义字段 纸壳CMS现已支持自定义字段,在不修改代码的情况下, ...
- SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件
需求 SparkContext自定义扩展textFiles,支持从多个目录中输入文本文件 扩展 class SparkContext(pyspark.SparkContext): def ...
- WCF自定义扩展,以实现aop!
引用地址:https://msdn.microsoft.com/zh-cn/magazine/cc163302.aspx 使用自定义行为扩展 WCF Aaron Skonnard 代码下载位置: S ...
- 第十三节:HttpHander扩展及应用(自定义扩展名、图片防盗链)
一. 自定义扩展名 1. 前言 凡是实现了IHttpHandler接口的类均为Handler类,HttpHandler是一个HTTP请求的真正处理中心,在HttpHandler容器中,ASP.NET ...
- SharePoint 2013 自定义扩展菜单
在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...
- Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)
Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...
- 工作随笔——selenium支持post请求,支持自定义header
背景: 最近在写一个小程序,发现博主所在的地区访问该网站时有防ddos功能验证导致程序不能正常工作. 经过试验发现可以用国外代理ip解决这个问题,但是程序走代理访问延迟高且不稳定. 思路: selen ...
- Asp.Net Mvc 自定义扩展
目录: 自定义模型IModelBinder 自定义模型验证 自定义视图引擎 自定义Html辅助方法 自定义Razor辅助方法 自定义Ajax辅助方法 自定义控制器扩展 自定义过滤器 自定义Action ...
- 第一步 使用sencha touch cmd 4.0 创建项目、打包(加入全局变量、公用类、自定义扩展、资源文件)
参考资料: http://www.cnblogs.com/qqloving/archive/2013/04/25/3043606.html http://www.admin10000.com/docu ...
随机推荐
- let, const用法以及与var的区别
let 定义变量; 作用域:全局作用域,块级作用域(简单说,是指一对大括号{}): 无预解析机制(简单说,变量需要在声明的位置后面使用): 不可以重复定义. const 定义常量: 作用域: 块级作用 ...
- flink启动报错:java.lang.NoSuchMethodError: org.apache.flink.api.java.ClosureCleaner.clean(Ljava/lang/Object;Z)V
这是因为pom文件引入的flink相关依赖设置成了provided 作用域 要嘛把这个去掉 但是如果是IDEA的话 可以更简单的操作 把这个打勾保存 接着重新启动main方法即可
- 【LeetCode】890. Find and Replace Pattern 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典+set 单字典 日期 题目地址:https:/ ...
- 突破技术限制,实现Web端静默打印
作为Web开发的同僚们,估计都有一个共同的烦恼,Web端为什么不能够像 CS端那样直接打印预览?直接移除掉打印预览界面不就可以了? 真实情况是Web端受限于浏览器的权限,无法直接访问打印机等本机资源. ...
- Java基础(八)——IO流1_字节流、字符流
一.概述 1.介绍 I/O是 Input/Output 的缩写,IO流用来处理设备之间的数据传输,如读/写文件,网络通讯等.Java对数据的操作是通过流的方式进行.java.io 包下提供了各种&qu ...
- Spring事务的基本原理
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.. 对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获取连接 Connecti ...
- css的鼠标手势总结
css的鼠标手势 cursor:pointer; 或 cursor:hand : 手型 cursor:crosshair : 十字 cursor:text : 文本 cursor:wait : 等待 ...
- SRGAN
目录 概 主要内容 代码 Ledig C., Theis L., Huszar F., Caballero J., Cunningham A., Acosta A., Aitken A., Tejan ...
- CS5211替代兼容PS8625|普瑞PS8625替代方案|CapstoneCS5211
PS8625是一个DP显示端口 到LVDS转换器芯片,利用GPU和显示端口(DP) 或嵌入式显示端口(eDP) 输出和接受LVDS输入的显示面板.PS8625实现双通道DP输入,双链路LVDS输出.P ...
- centos7 安装python3 小白教程-CV大法
安装python3 centos7,默认系统自带python2.7的版本,这个版本被系统很多程序所依赖,所以不建议删除,如果使用最新的Python3那么我们知道编译安装源码包和系统默认包之间是没有任何 ...