Python + requests实现接口自动化框架!_python requests 接口自动化

读取日志配置文件

logging.config.fileConfig(baseDir + “\config\Logger.conf”)

选择一个日志格式

logger = logging.getLogger(“example02”)#或者example01

def debug(message):

定义dubug级别日志打印方法

logger.debug(message)

def info(message):

定义info级别日志打印方法

logger.info(message)

def warning(message):

定义warning级别日志打印方法

logger.warning(message)

3.5 封装发送Email类

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from ProjVar.var import *

import os
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import formataddr

def send_mail():
mail_host=“smtp.qq.com” #设置服务器
mail_user=“xiangxiang” #用户名
mail_pass=“cmxx” #口令
sender = ‘cm2019@126.com’
receivers = [‘672014873@qq.com’,“cm2019@126.com”] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

创建一个带附件的实例

message = MIMEMultipart()
message[‘From’] = formataddr([“自动化测试”, “cm2019@126.com”])
message[‘To’] = ‘,’.join(receivers)
subject = ‘自动化测试执行报告’
message[‘Subject’] = Header(subject, ‘utf-8’)
message[“Accept-Language”]=“zh-CN”
message[“Accept-Charset”]=“ISO-8859-1,utf-8,gbk”

邮件正文内容

message.attach(MIMEText(‘最新执行的自动化测试报告,请参阅附件内容!’, ‘plain’, ‘utf-8’))

构造附件1,传送测试结果的excel文件

att = MIMEBase(‘application’, ‘octet-stream’)
att.set_payload(open(ProjDirPath+“\testdata\testdata.xlsx”, ‘rb’).read())
att.add_header(‘Content-Disposition’, ‘attachment’, filename=(‘gbk’, ‘’, “自动化测试报告.xlsx”))
encoders.encode_base64(att)
message.attach(att)
“”"

构造附件2,传送当前目录下的 runoob.txt 文件

att2 = MIMEText(open(‘e:\a.py’,‘rb’).read(), ‘base64’, ‘utf-8’)
att2[“Content-Type”] = ‘application/octet-stream’
att2[“Content-Disposition”] = ‘attachment; filename=“a.py”’
message.attach(att2)
“”"
try:
smtpObj = smtplib.SMTP(mail_host)
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print(“邮件发送成功”)
except smtplib.SMTPException as e:
print(“Error: 无法发送邮件”, e)

if name == “main”:
send_mail()

四、 创建config包 用来存放公共的参数、配置文件、长时间不变的变量值

创建public_data.p

import os

整个项目的根目录绝对路劲

baseDir = os.path.dirname(os.path.dirname(file))

获取测试数据文件的绝对路径

file_path = baseDir + “/TestData/inter_test_data.xlsx”

API_apiName = 2
API_requestUrl = 3
API_requestMothod = 4
API_paramsType = 5
API_apiTestCaseFileName = 6
API_active = 7

CASE_requestData = 1
CASE_relyData = 2
CASE_responseCode = 3
CASE_responseData = 4
CASE_dataStore = 5
CASE_checkPoint = 6
CASE_active = 7
CASE_status = 8
CASE_errorInfo = 9

存储请求参数里面依赖的数据

REQUEST_DATA = {}

存储响应对象中的依赖数据

RESPONSE_DATA = {}

if name==“main”:
print(file_path)
print(baseDir)

五、创建TestData目录,用来存放测试文件

inter_test_data.xlsx

六、创建action包,用来存放关键字函数
6.1 解决数据依赖 (GetRely.py)

from config.public_data import REQUEST_DATA, RESPONSE_DATA
from utils.md5_encrypt import md5_encrypt

REQUEST_DATA = {“用户注册”:{“1”:{“username”:“zhangsan”, “password”:“dfsdf23”},
“headers”:{“cookie”:“asdfwerw”}}}
RESPONSE_DATA = {“用户注册”:{“1”:{“code”:“00”}, “headers”:{“age”:2342}}}

class GetRely(object):
def init(self):
pass

@classmethod
def get(self, dataSource, relyData, headSource = {}):
print(type(dataSource))
print(dataSource)
data = dataSource.copy()
for key, value in relyData.items():
if key == “request”:
#说明应该去REQUEST_DATA中获取
for k, v in value.items():
interfaceName, case_idx = v.split(“->”)
val = REQUEST_DATA[interfaceName][case_idx][k]
if k == “password”:
data[k] = md5_encrypt(val)
else:
data[k] = val
elif key == “response”:

应该去RESPONSE_DATA中获取

for k, v in value.items():
interfaceName, case_idx = v.split(“->”)
data[k] = RESPONSE_DATA[interfaceName][case_idx][k]
elif key == “headers”:
if headSource:
for key, value in value.items():
if key == “request”:
for k, v in value.items():
for i in v:
headSource[i] = REQUEST_DATA[k][“headers”][i]
elif key == “response”:
for i, val in value.items():
for j in val:
headSource[j] = RESPONSE_DATA[i][“headers”][j]
return “%s” %data

if name == “main”:
s = {“username”: “”, “password”: “”,“code”:“”}
h = {“cookie”:“123”, “age”:332}
rely = {“request”: {“username”: “用户注册->1”, “password”: “用户注册->1”},
“response”:{“code”:“用户注册->1”},
“headers”:{“request”:{“用户注册”:[“cookie”]},“response”:{“用户注册”:[“age”]}}
}
print(GetRely.get(s, rely, h))

6.2 解决数据存储(RelyDataStore.y)

from config.public_data import RESPONSE_DATA, REQUEST_DATA

class RelyDataStore(object):
def init(self):
pass

@classmethod
def do(cls, storePoint, apiName, caseId, request_source = {}, response_source = {}, req_headers={}, res_headers = {}):
for key, value in storePoint.items():
if key == “request”:

说明需要存储的依赖数据来自请求参数,应该将数据存储到REQUEST_DATA

for i in value:
if i in request_source:
val = request_source[i]
if apiName not in REQUEST_DATA:

说明存储数据的结构还未生成,需要指明数据存储结构

REQUEST_DATA[apiName]={str(caseId): {i: val}}
else:
#说明存储数据结构中最外层结构已存在
if str(caseId) in REQUEST_DATA[apiName]:
REQUEST_DATA[apiName][str(caseId)][i] = val
else:

说明内层结构不完整,需要指明完整的结构

REQUEST_DATA[apiName][str(caseId)] = {i: val}
else:
print(“请求参数中不存在字段” + i)
elif key == “response”:
#说明需要存储的依赖数据来自接口的响应body,应该将数据存储到RESPONSE_DATA
for j in value:
if j in response_source:
val = response_source[j]
if apiName not in RESPONSE_DATA:

说明存储数据的结构还未生成,需要指明数据存储结构

RESPONSE_DATA[apiName]={str(caseId): {j: val}}
else:
#说明存储数据结构中最外层结构已存在
if str(caseId) in RESPONSE_DATA[apiName]:
RESPONSE_DATA[apiName][str(caseId)][j] = val
else:

说明内层结构不完整,需要指明完整的结构

RESPONSE_DATA[apiName][str(caseId)] = {j: val}
else:
print(“接口的响应body中不存在字段” + j)
elif key == “headers”:
for k, v in value.items():
if k == “request”:

说明需要往REQUEST_DATA变量中写入存储数据

for item in v:
if item in req_headers:
header = req_headers[item]
if “headers” in REQUEST_DATA[apiName]:
REQUEST_DATA[apiName][“headers”][item] = header
else:
REQUEST_DATA[apiName][“headers”] = {item: header}
elif k == “response”:

说明需要往RESPONSE_DATA变量中写入存储数据

for it in v:
if it in res_headers:
header = res_headers[it]
if “headers” in RESPONSE_DATA[apiName]:
RESPONSE_DATA[apiName][“headers”][it] = header
else:
RESPONSE_DATA[apiName][“headers”] = {item: header}
print(REQUEST_DATA)
print(RESPONSE_DATA)

if name == “main”:
r = {“username”: “srwcx01”, “password”: “wcx123wac1”, “email”: “wcx@qq.com”}
req_h = {“cookie”:“csdfw23”}
res_h = {“age”:597232}
s = {“request”: [“username”, “password”], “response”: [“userid”],“headers”:{“request”:[“cookie”],
“response”:[“age”]}}
res = {“userid”: 12, “code”: “00”}
RelyDataStore.do(s, “register”, 1, r, res, req_headers=req_h, res_headers=res_h)
print(REQUEST_DATA)
print(RESPONSE_DATA)

6.3 校验数据结果(CheckResult.py)

import re

class CheckResult(object):
def init(self):
pass

@classmethod
def check(self, responseObj, checkPoint):
responseBody = responseObj.json()

responseBody = {“code”: “”, “userid”: 12, “id”: “12”}

errorKey = {}
for key, value in checkPoint.items():
if key in responseBody:
if isinstance(value, (str, int)):

等值校验

if responseBody[key] != value:
errorKey[key] = responseBody[key]
elif isinstance(value, dict):
sourceData = responseBody[key]
if “value” in value:

模糊匹配校验

regStr = value[“value”]
rg = re.match(regStr, “%s” %sourceData)
if not rg:
errorKey[key] = sourceData
elif “type” in value:

数据类型校验

typeS = value[“type”]
if typeS == “N”:

说明是整形校验

if not isinstance(sourceData, int):
errorKey[key] = sourceData
else:
errorKey[key] = “[%s] not exist” %key
return errorKey

if name == “main”:
r = {“code”: “00”, “userid”: 12, “id”: 12}
c = {“code”: “00”, “userid”: {“type”: “N”}, “id”: {“value”: “\d+”}}
print(CheckResult.check(r, c))

6.4 往excel里面写结果

from config.public_data import *

def write_result(wbObj, sheetObj, responseData, errorKey, rowNum):
try:

写响应body

wbObj.writeCell(sheetObj, content=“%s” %responseData,
rowNo = rowNum, colsNo=CASE_responseData)

写校验结果状态及错误信息

if errorKey:
wbObj.writeCell(sheetObj, content=“%s” %errorKey,
rowNo=rowNum, colsNo=CASE_errorInfo)
wbObj.writeCell(sheetObj, content=“faild”,
rowNo=rowNum, colsNo=CASE_status, style=“red”)
else:
wbObj.writeCell(sheetObj, content=“pass”,
rowNo=rowNum, colsNo=CASE_status, style=“green”)
except Exception as err:
raise err

七、创建Log目录用来存放日志
八、主函数

#encoding=utf-8
import requests
import json
from action.get_rely import GetRely
from config.public_data import *
from utils.ParseExcel import ParseExcel
from utils.HttpClient import HttpClient
from action.data_store import RelyDataStore
from action.check_result import CheckResult
from action.write_result import write_result
from utils.Log import *

def main():
parseE = ParseExcel()
parseE.loadWorkBook(file_path)
sheetObj = parseE.getSheetByName(“API”)
activeList = parseE.getColumn(sheetObj, API_active)
for idx, cell in enumerate(activeList[1:], 2):
if cell.value == “y”:
#需要被执行
RowObj = parseE.getRow(sheetObj, idx)
apiName = RowObj[API_apiName -1].value
requestUrl = RowObj[API_requestUrl - 1].value
requestMethod = RowObj[API_requestMothod - 1].value
paramsType = RowObj[API_paramsType - 1].value
apiTestCaseFileName = RowObj[API_apiTestCaseFileName - 1].value

下一步读取用例sheet表,准备执行测试用例

caseSheetObj = parseE.getSheetByName(apiTestCaseFileName)
caseActiveObj = parseE.getColumn(caseSheetObj, CASE_active)
for c_idx, col in enumerate(caseActiveObj[1:], 2):
if col.value == “y”:
#需要执行的用例
caseRowObj = parseE.getRow(caseSheetObj, c_idx)
requestData = caseRowObj[CASE_requestData - 1].value
relyData = caseRowObj[CASE_relyData - 1].value
responseCode = caseRowObj[CASE_responseCode - 1].value
responseData = caseRowObj[CASE_responseData - 1].value
dataStore = caseRowObj[CASE_dataStore -1].value
checkPoint = caseRowObj[CASE_checkPoint - 1].value

#发送接口请求之前需要做一下数据依赖的处理
if relyData:
logging.info(“处理第%s个接口的第%s条用例的数据依赖!”)
requestData = GetRely.get(eval(requestData), eval(relyData))
httpC = HttpClient()
response = httpC.request(requestMethod=requestMethod,
requestData=requestData,
requestUrl=requestUrl,
paramsType=paramsType
)

获取到响应结果后,接下来进行数据依赖存储逻辑实现

if response.status_code == 200:
responseData = response.json()

进行依赖数据存储

if dataStore:
RelyDataStore.do(eval(dataStore), apiName, c_idx - 1, eval(requestData), responseData)

接下来就是校验结果

else:
logging.info(“接口【%s】的第【%s】条用例,不需要进行依赖数据存储!” %(apiName, c_idx))
if checkPoint:
errorKey = CheckResult.check(response, eval(checkPoint))
write_result(parseE, caseSheetObj, responseData, errorKey, c_idx)
else:
logging.info(“接口【%s】的第【%s】条用例,执行失败,接口协议code非200!” %(apiName, c_idx))
else:
logging.info(“第%s个接口的第%s条用例,被忽略执行!” %(idx -1, c_idx-1))
else:
logging.info(“第%s行的接口被忽略执行!” %(idx -1))

if name==“main”:
main()

框架待完善,请大家多多指教~
以上内容希望对你有帮助,有被帮助到的朋友欢迎点赞,评论。

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

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

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

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

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

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

sXz-1712693865953)]
[外链图片转存中…(img-WjyKBC52-1712693865953)]
[外链图片转存中…(img-ZYrq925O-1712693865953)]
[外链图片转存中…(img-5I3CffM0-1712693865954)]

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

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

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-d27RWSj9-1712693865954)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
接口自动化测试框架是一种用于管理和执行接口测试用例的工具。Python语言结合pytest和requests库可以很方便地实现接口自动化测试框架。 首先,你需要安装pytest和requests库。可以使用以下命令安装它们: ``` pip install pytest pip install requests ``` 接下来,创建一个测试用例文件,例如`test_api.py`,并导入所需的库: ```python import pytest import requests ``` 然后,编写测试用例函数。使用pytest的装饰器`@pytest.mark.parametrize`可以方便地实现参数化测试。 ```python @pytest.mark.parametrize("url, expected_status_code", [ ("https://api.example.com/users", 200), ("https://api.example.com/posts", 200), ("https://api.example.com/comments", 200), ]) def test_api(url, expected_status_code): response = requests.get(url) assert response.status_code == expected_status_code ``` 在上面的示例中,我们定义了三个测试用例函数,每个测试用例函数都会发送一个GET请求并断言响应的状态码是否与期望的状态码一致。 最后,使用pytest命令来运行测试用例: ``` pytest test_api.py ``` pytest会自动发现并执行所有以`test_`开头的函数作为测试用例。 通过以上步骤,你就可以使用Python+pytest+requests构建一个简单的接口自动化测试框架,并使用unittest风格的方式管理测试用例。当然,你还可以根据实际需求添加更多的功能,例如报告生成、测试数据管理等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值