当前位置:   article > 正文

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

requests.reques接口自动化

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Python全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img



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

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

如果你需要这些资料,可以添加V获取:vip1024c (备注Python)
img

正文

6、运行主程序interface_auto_test.py

7、Readme.txt:告诉团队组员使用改框架需要注意的地方

二、接口的数据规范设计—Case设计

一个sheet对应数据库里面一张表

APIsheet存放
编号;从1开始
接口的名称(APIName);
请求的url(RequestUrl);
请求的方法(RequestMethod);
传参的方式(paramsType):post/get请求方法不一样
用例说明(APITestCase)
是否执行(Active)部分接口已测通,下次不用测试,直接把这里设置成N,跳过此接口

post与get的区别

查看post详情

post请求参数一般是json串,参数放在from表单里面;参数一般不可见,相对来说安全性高些

查看get详情

get请求参数一般直接放在url里面

2.1注册接口用例

RequestData:请求的数据
(开发制定的传参方式)
RelyData:数据依赖
ResponseCode:响应code
ResponseData:响应数据
DataStore:存储的依赖数据;如果存在数据库里面,在表里增加一个字段用来存依赖的数据
(存储的方式是编写接口自动化的人员来设定的存储方式)
CheckPoint:检查点
Active:是否执行
Status:执行用例的状态,方便查看用例是否执行成功
ErrorInfo:case运行失败,失败的错误信息;eg:是也本身的原因还是case设置失败,还是其他原因

2.2登录接口用例

RequestData:请求的数据
(开发制定的传参方式)
RelyData:数据依赖
(存储的方式是编写接口自动化的人员来设定的存储方式)
ResponseCode:响应code
ResponseData:响应数据
DataStore:存储的依赖数据;如果存在数据库里面,在表里增加一个字段用来存依赖的数据
(存储的方式是编写接口自动化的人员来设定的存储方式)
CheckPoint:检查点
Active:是否执行
Status:执行用例的状态,方便查看用例是否执行成功
ErrorInfo:case运行失败,失败的错误信息;eg:是也本身的原因还是case设置失败,还是其他原因

重点说明下RelyData:数据依赖
采取的是字典:key:value来存储数据格式;

{“request”:{“username”:“register->1”,“password”:“register->1”},“response”:{“code”:“register->1”}}

格式化之后:

{
    "request":{
        "username":"register->1",
        "password":"register->1"
    },
    "response":{
        "code":"register->1"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
三、创建utils包:用来存放公共的类
3.1 ParseExcel.py 操作封装excel的类(ParseExcel.py)
#encoding=utf-8
import openpyxl
from openpyxl.styles import Border, Side, Font
import time

class ParseExcel(object):

    def __init__(self):
        self.workbook = None
        self.excelFile = None
        self.font = Font(color = None) # 设置字体的颜色
        # 颜色对应的RGB值
        self.RGBDict = {'red': 'FFFF3030', 'green': 'FF008B00'}

    def loadWorkBook(self, excelPathAndName):
        # 将excel文件加载到内存,并获取其workbook对象
        try:
            self.workbook = openpyxl.load_workbook(excelPathAndName)
        except Exception as err:
            raise err
        self.excelFile = excelPathAndName
        return self.workbook

    def getSheetByName(self, sheetName):
        # 根据sheet名获取该sheet对象
        try:
            # sheet = self.workbook.get_sheet_by_name(sheetName)
            sheet = self.workbook[sheetName]
            return sheet
        except Exception as err:
            raise err

    def getSheetByIndex(self, sheetIndex):
        # 根据sheet的索引号获取该sheet对象
        try:
            # sheetname = self.workbook.get_sheet_names()[sheetIndex]
            sheetname = self.workbook.sheetnames[sheetIndex]
        except Exception as err:
            raise err
        # sheet = self.workbook.get_sheet_by_name(sheetname)
        sheet = self.workbook[sheetname]
        return sheet

    def getRowsNumber(self, sheet):
        # 获取sheet中有数据区域的结束行号
        return sheet.max_row

    def getColsNumber(self, sheet):
        # 获取sheet中有数据区域的结束列号
        return sheet.max_column

    def getStartRowNumber(self, sheet):
        # 获取sheet中有数据区域的开始的行号
        return sheet.min_row

    def getStartColNumber(self, sheet):
        # 获取sheet中有数据区域的开始的列号
        return sheet.min_column

    def getRow(self, sheet, rowNo):
        # 获取sheet中某一行,返回的是这一行所有的数据内容组成的tuple,
        # 下标从1开始,sheet.rows[1]表示第一行
        try:
            rows = []
            for row in sheet.iter_rows():
                rows.append(row)
            return rows[rowNo - 1]
        except Exception as err:
            raise err

    def getColumn(self, sheet, colNo):
        # 获取sheet中某一列,返回的是这一列所有的数据内容组成tuple,
        # 下标从1开始,sheet.columns[1]表示第一列
        try:
            cols = []
            for col in sheet.iter_cols():
                cols.append(col)
            return cols[colNo - 1]
        except Exception as err:
            raise err

    def getCellOfValue(self, sheet, coordinate = None,
                       rowNo = None, colsNo = None):
        # 根据单元格所在的位置索引获取该单元格中的值,下标从1开始,
        # sheet.cell(row = 1, column = 1).value,
        # 表示excel中第一行第一列的值
        if coordinate != None:
            try:
                return sheet[coordinate]
            except Exception as err:
                raise err
        elif coordinate is None and rowNo is not None and \
                        colsNo is not None:
            try:
                return sheet.cell(row = rowNo, column = colsNo).value
            except Exception as err:
                raise err
        else:
            raise Exception("Insufficient Coordinates of cell !")

    def getCellOfObject(self, sheet, coordinate = None,
                        rowNo = None, colsNo = None):
        # 获取某个单元格的对象,可以根据单元格所在位置的数字索引,
        # 也可以直接根据excel中单元格的编码及坐标
        # 如getCellObject(sheet, coordinate = 'A1') or
        # getCellObject(sheet, rowNo = 1, colsNo = 2)
        if coordinate != None:
            try:
                # return sheet.cell(coordinate = coordinate)
                return sheet[coordinate]
            except Exception as err:
                raise err
        elif coordinate == None and rowNo is not None and \
                        colsNo is not None:
            try:
                return sheet.cell(row = rowNo,column = colsNo)
            except Exception as err:
                raise err
        else:
            raise Exception("Insufficient Coordinates of cell !")

    def writeCell(self, sheet, content, coordinate = None,
        rowNo = None, colsNo = None, style = None):
        #根据单元格在excel中的编码坐标或者数字索引坐标向单元格中写入数据,
        # 下标从1开始,参style表示字体的颜色的名字,比如red,green
        if coordinate is not None:
            try:
                # sheet.cell(coordinate = coordinate).value = content
                sheet[coordinate] = content
                if style is not None:
                    sheet[coordinate].\
                        font = Font(color = self.RGBDict[style])
                self.workbook.save(self.excelFile)
            except Exception as e:
                raise e
        elif coordinate == None and rowNo is not None and \
                        colsNo is not None:
            try:
                sheet.cell(row = rowNo,column = colsNo).value = content
                if style:
                    sheet.cell(row = rowNo,column = colsNo).\
                        font = Font(color = self.RGBDict[style])
                self.workbook.save(self.excelFile)
            except Exception as e:
                raise e
        else:
            raise Exception("Insufficient Coordinates of cell !")

    def writeCellCurrentTime(self, sheet, coordinate = None,
                rowNo = None, colsNo = None):
        # 写入当前的时间,下标从1开始
        now = int(time.time())  #显示为时间戳
        timeArray = time.localtime(now)
        currentTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
        if coordinate is not None:
            try:
                sheet.cell(coordinate = coordinate).value = currentTime
                self.workbook.save(self.excelFile)
            except Exception as e:
                raise e
        elif coordinate == None and rowNo is not None \
                and colsNo is not None:
            try:
                sheet.cell(row = rowNo, column = colsNo
                        ).value = currentTime
                self.workbook.save(self.excelFile)
            except Exception as e:
                raise e
        else:
            raise Exception("Insufficient Coordinates of cell !")

if __name__ == '__main__':
    # 测试代码
    pe = ParseExcel()
    pe.loadWorkBook(r'D:\ProgramSourceCode\Python Source Code\WorkSpace\InterfaceFrame2018\inter_test_data.xlsx')
    sheetObj = pe.getSheetByName(u"API")
    print("通过名称获取sheet对象的名字:", sheetObj.title)
    # print help(sheetObj.rows)
    print("通过index序号获取sheet对象的名字:", pe.getSheetByIndex(0).title)
    sheet = pe.getSheetByIndex(0)
    print(type(sheet))
    print(pe.getRowsNumber(sheet))  #获取最大行号
    print(pe.getColsNumber(sheet))  #获取最大列号
    rows = pe.getRow(sheet, 1)  #获取第一行
    for i in rows:
        print(i.value)
    # # 获取第一行第一列单元格内容
    # print pe.getCellOfValue(sheet, rowNo = 1, colsNo = 1)
    # pe.writeCell(sheet, u'我爱祖国', rowNo = 10, colsNo = 10)
    # pe.writeCellCurrentTime(sheet, rowNo = 10, colsNo = 11)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.2 封装get/post请求(HttpClient.py)
import requests
import json

class HttpClient(object):
    def __init__(self):
        pass

    def request(self, requestMethod, requestUrl, paramsType,
                requestData, headers =None, **kwargs):
        if requestMethod == "post":
            print("---", requestData, type(requestData))
            if paramsType == "form":
                response = self.__post(url = requestUrl, data = json.dumps(eval(requestData)),
                                  headers = headers, **kwargs)
                return response
            elif paramsType == "json":
                response = self.__post(url = requestUrl, json = json.dumps(eval(requestData)),
                                  headers = headers, **kwargs)
                return response
        elif requestMethod == "get":
            request_url = requestUrl
            if paramsType == "url":
                request_url = "%s%s" %(requestUrl, requestData)
            response = self.__get(url = request_url, params = requestData, **kwargs)
            return response

    def __post(self, url, data = None, json = None, headers=None,**kwargs):
        print("----")
        response = requests.post(url=url, data = data, json=json, headers=headers)
        return response

    def __get(self, url, params = None, **kwargs):
        response = requests.get(url, params = params, **kwargs)
        return response

if __name__ == "__main__":
    hc = HttpClient()
    res = hc.request("get", "http://39.106.41.11:8080/getBlogContent/", "url",'2')
    print(res.json())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
3.3 封装MD5(md5_encrypt)
import hashlib

def md5_encrypt(text):
    m5 = hashlib.md5()
    m5.update(text.encode("utf-8"))
    value = m5.hexdigest()
    return value

if __name__ == "__main__":
    print(md5_encrypt("sfwe"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
3.4 封装Log
import logging
import logging.config
from config.public_data import baseDir

# 读取日志配置文件
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
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()
​
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
四、 创建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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
五、创建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}}}


### 最后

> **
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/821001
推荐阅读
相关标签