python-自动化测试- 多接口动态参数设计

1、环境变量里已经有了 属性名 --属性值
class EnviData:
prodId = 7717
skuId = 4563
2、先从类里获取属性值 – getattr(EnviData,prodId) === prodId这个名字
3、先用正则找到这个字符串里的 占位符标记的字符串 ,replace(标记符,类属性值)

注意: 做的事情

  • 第一个: 取到 #prodId# == 被替换掉的子字符串
  • 第二个: prodId == 获取类属性变量。
    “”"

import re

str_data = ‘{“basketId”: 0, “count”: 1, “prodId”: #prodId#, “shopId”: 1, “skuId”: #skuId#}’

findall(正则表达式, 目标字符串) ,字符串从头到尾去匹配,只要符合要求就会拿出来

result = re.findall(“#.*?#”,str_data) # 结果是 #prodId#
print(result)

得到## 限定符里面的变量名:–加上括号就只会得到 #里面的值#

var_name = re.findall(“#(.*?)#”,str_data) #结果 prodId
print(var_name)

search(正则表达式, 目标字符串)方法

result = re.search(“#(.*?)#”,str_data) # 结果是一个对象
print(result)

对象的group()方法 - 正则分组,可以返回的匹配的整体子串

value = result.group() # 结果是 #prodId#
print(value)
var_name = result.group(1) # 第一个分组的值 结果是 prodId
print(var_name)

没有匹配到结果–None

result = re.search(“#.*?!#”,str_data) # 结果是一个对象
print(result)


运行结果如下:



[‘#prodId#’, ‘#skuId#’]
[‘prodId’, ‘skuId’]
<re.Match object; span=(38, 46), match=‘#prodId#’>
#prodId#
prodId
None


### 循环正则提取



“”"
*
re模块函数 : findall(),search()
* findall(正则表达式, 目标字符串) ,字符串从头到尾去匹配,只要符合要求就会拿出来
* 多个符合的结果 存到列表里,返回一个列表。
* 如果只想获取里面的变量名 不需要这个## 限定符,可以加个括号括起来: 加了括号,就是只提取括号里的内容,## 就是左右边界了。
* search(正则表达式, 目标字符串)方法
* 搜索查找,如果匹配的正则符合的话,返回Match类型的对象,不符合就返回None
* Match类型的对象(search函数的返回值)的方法group() - 正则分组,可以返回的匹配的整体子串-整体占位符内容 #prodId#
* search函数找到了第一个符合的之后,它就不会再继续往后去查找

  • 循环找: 先找到第一个,替换掉这个; 继续第二次,替换掉,第三次。。。。
  • 确定循环次数么?–不能确认循环次数的时候,用while。
  • while循环先进去,找不到占位符 – 返回值None ,跳出循环。

思路:
1、环境变量里已经有了 属性名 --属性值
class EnviData:
prodId = 7717
skuId = 4563
2、先从类里获取属性值 – getattr(EnviData,prodId) === prodId这个名字
3、先用正则找到这个字符串里的 占位符标记的字符串 ,replace(标记符,类属性值)

注意: 做的事情

  • 第一个: 取到 #prodId# == 被替换掉的子字符串
  • 第二个: prodId == 获取类属性变量。
    “”"

import re

str_data = ‘{“basketId”: 0, “count”: 1, “prodId”: #prodId#, “shopId”: 1, “skuId”: #skuId#}’
class EnviData:
prodId = 7717
skuId = 4563

while True:
# search(正则表达式, 目标字符串)方法
result = re.search(“#(.*?)#”,str_data) # 结果是一个对象
if result is None: # 如果没有占位符 就是None 跳出循环
break
mark = result.group() # 结果是 #prodId# --要被替换的子字符串
var_name = result.group(1) # 第一个分组的值 结果是 prodId
# 从环境变量里获取变量名对应的属性值 prodId-- 属性值 7717,替换的数据
var_value = getattr(EnviData,var_name) # 结果 : 7717–int类型
# 目标字符串的替换,赋值给一个变量
# 注意:replace方法要求 两个参数都应该是字符串。
str_data = str_data.replace(mark,str(var_value))
print(str_data)


运行结果如下:



{“basketId”: 0, “count”: 1, “prodId”: 7717, “shopId”: 1, “skuId”: #skuId#}
{“basketId”: 0, “count”: 1, “prodId”: 7717, “shopId”: 1, “skuId”: 4563}


## 多接口动态参数封装


提取响应结果的函数 – 是在接口执行完成后 得到响应结果  
 都需要在requests\_api函数里扩展 ==对应的位置调用这两个函数就可以了。


### 提取响应结果的函数 – 是在接口执行完成后 得到响应结果


handle\_replace.py 内容如下:



“”"
1、def封装
2、参数化
3、返回值: 最终要拿到替换后的字符串 — 头部 参数 要用于发送接口测试的
4、加上日志: 但凡你想确认数据结果的地方 都可以加上日志
5、因为有些接口不需要做数据提取,所以判空处理:
6、异常捕获: 因为有可能环境变量里没有这个属性名 和属性值

“”"
import re
from loguru import logger
from tools.envi_data import EnviData

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# --要被替换的子字符串
logger.info(f"要被替换的子字符串:{mark}“)
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.replace(mark,str(var_value))
logger.info(f"替换完成后的字符串是:{str_data}")
return str_data

if name == ‘__main__’:
str_data = ‘{“basketId”: 0, “count”: 1, “prodId”: #prodId#, “shopId”: 1, “skuId”: #skuId#}’
replace_mark(str_data)


### 替换头部和参数里的占位符的函数 – 是在发送接口请求之前


envi\_data.py内容如下:



这个类就是为了存储环境变量 实现环境变量的共享的

class EnviData:
pass


handle\_extract.py 内容(获取需要提取的字段名)如下:



“”"
1、def封装
2、参数化
3、返回值: 因为数据都存在环境变量 所以不需要返回值
4、加上日志: 但凡你想确认数据结果的地方 都可以加上日志
5、因为有些接口不需要做数据提取,所以判空处理:

“”"

import json
from jsonpath import jsonpath
from loguru import logger
from tools.envi_data import EnviData

def extract_response(response,extract_data):
# 因为有些接口不需要做数据提取,所以判空处理:
if extract_data is None:
logger.info(“这条用例不需要做响应结果的数据提取!”)
return
# 第一步: 反序列化 -字典
logger.info(“-----------------响应结果提取开始------------------------------”)
extract_data = json.loads(extract_data)
logger.info(f"提取的向红结果的表达式是:{extract_data}“)
for k,v in extract_data.items(): # k 是access_token 变量名字,v是$…access_token
# 使用jsonpath表达式 提取login响应结果里的值
value = jsonpath(response.json(),v)[0] # 是access_token的具体值
# 存起来到环境变量里去
setattr(EnviData,k,value)
logger.info(f"提取并设置环境变量之后的类属性是:{EnviData.__dict__}”)

if name == ‘__main__’:
response = {“access_token”: “0efdce50-0e2f-4ed0-b4d1-944be5ab518a”,
“token_type”: “bearer”, “refresh_token”: “4bfc3638-e7e4-4844-a83d-c0f8340bc146”,
“expires_in”: 1295999,
“pic”: “http://mall.lemonban.com:8108/2023/09/b5a479b28d514aa59dfa55422b23a6f0.jpg”,
“userId”: “46189bfd628e4a738f639017f1d9225d”, “nickName”: “lemon_auto”, “enabled”: True}

extract_data = '{"access\_token":"$..access\_token","token\_type":"$..token\_type"}'
extract_response(response,extract_data)

handle\_requests.py文件如下:



“”"
方法优化:
1、日志加上

2、测试用例方法里调用夹具 获取返回值。

  • 更新requests-api,需要做token处理:
  • 设置一个默认参数:token = None
  • 如果接口需要鉴权,测试用例里调用夹具,得到token,requests_api传递token参数;–requests 更新头部
  • 如果接口不需要鉴权: token不传 None。 不会做更新头部的操作。

“”"

import json
import requests
from tools.handle_path import pic_path
from loguru import logger
from tools.handle_extract import extract_response
from tools.handle_replace import replace_mark

def requests_api(casedata,token=None):
method = casedata[“请求方法”]
url = casedata[“接口地址”]
headers = casedata[“请求头”]
params = casedata[“请求参数”]
# 在发送请求之前完成头部和参数的替换–调用替换的函数==结果是字符串
headers = replace_mark(headers)
params = replace_mark(params)
# 反序列操作: 结合判空处理,
if headers is not None:
headers = json.loads(headers)
if token is not None: # 这是做接口如果需要鉴权,传进来token 更新头部信息。
headers[“Authorization”] = token # 字典新增 / 修改
if params is not None:
params = json.loads(params)
logger.info(“---------------------------请求消息-----------------------------------”)
logger.info(f"请求方法是{method}“)
logger.info(f"请求地址是{url}”)
logger.info(f"请求头部是{headers}“)
logger.info(f"请求参数是{params}”)
#接口请求可能是get post put等各种请求方法 分支判断
if method.lower() == “get”:
resp = requests.request(method=method, url=url, params=params,headers=headers)
elif method.lower() == “post”:
if headers is None:
logger.info(“头部为空,检查excel表格里头部信息!”)
return
# post请求:content-type的类型有关系。需要对每一种类型做处理 分支判断
if headers[“Content-Type”] == “application/json”:
resp = requests.request(method=method, url=url, json=params, headers=headers)
if headers[“Content-Type”] == “application/x-www-form-urlencoded”:
resp = requests.request(method=method, url=url, data=params, headers=headers)
if headers[“Content-Type”] == “multipart/form-data”:
# 发送请求的时候不能带上 ‘Content-Type’: ‘multipart/form-data’ 删除之后才发送接口请求。
headers.pop(“Content-Type”) # 字典删除元素
filename = params[“filename”] # 文件名字 值
file_obj = {“file”: (filename, open(pic_path/filename, “rb”))} # 文件参数
logger.info(f"文件接口的参数是:{file_obj}“)
logger.info(f"文件接口的头部是:{headers}”)
resp = requests.request(method=method, url=url,headers=headers,files=file_obj)
elif method.lower() == “put”:
pass
logger.info(“------------------------------响应消息-----------------------------”)
logger.info(f"接口响应状态码是:{resp.status_code}“)
logger.info(f"接口响应体是:{resp.text}”)
# 提取响应结果的数据-- 调用提取数据的函数
extract_response(resp,casedata[“提取响应字段”])
return resp




**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/0b9b0366cff644765c3c9401db99a724.png)

 

![img](https://img-blog.csdnimg.cn/img_convert/3e90e0f0cc6a0f9db6da7a6fcadc4ede.png)

![img](https://img-blog.csdnimg.cn/img_convert/46506ae54be168b93cf63939786134ca.png)

![img](https://img-blog.csdnimg.cn/img_convert/252731a671c1fb70aad5355a2c5eeff0.png)

![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)**

-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)

![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)**

<img src="https://img-community.csdnimg.cn/images/fd6ebf0d450a4dbea7428752dc7ffd34.jpg" alt="img" style="zoom:50%;" />
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值