接口自动化测试框架

article/2025/8/29 11:51:22

本文介绍一个接口自动化测试框架。

Python+unittest+requests

实现结果:读取Excel接口测试用例并执行,输出测试报告。

框架脑图

如图,各个模块及作用如上。

处理数据库

db_funcs用来处理数据库,实现数据库数据的读取操作。(如果没有用到则不需要)

import sqlite3
from config.ProjectConfig import ETConfig
from common.logger import write_logdef execute_db(sql):"""连接接口项目sqlite数据库,并执行sql语句:param sql: sql语句:return:"""try:# 打开数据库连接conn = sqlite3.connect("{0}\\studentManagementSystem\\db.sqlite3".format(ETConfig.PROJECT_DIR))# 新建游标cursor = conn.cursor()# 执行sqlcursor.execute(sql)# 获取执行结果result = cursor.fetchall()# 关闭游标、提交连接、关闭连接cursor.close()conn.commit()conn.close()return resultexcept sqlite3.OperationalError as e:write_log.error("数据库连接,执行失败:{}".format(e))def init_db():"""初始化数据库,删除掉departments的所有数据:return:"""execute_db("delete from departments;")if __name__ == '__main__':init_db()

处理Excel

用来对写在Excel中的测试用例进行读取,和测试结果的写回。


from openpyxl import load_workbook
class DoExcel:"""读写Excel文件"""def get_data(self,filename,sheetname):wb=load_workbook(filename)sheet=wb[sheetname]test_data=[]#读取Excel数据存入列表for i in range(2,sheet.max_row+1):row_data={}row_data['case_id'] = sheet.cell(i, 1).value #第一列为case_idrow_data['module']=sheet.cell(i,2).valuerow_data['title']=sheet.cell(i,3).valuerow_data['headers'] = sheet.cell(i, 4).valuerow_data['Cookie']=sheet.cell(i,5).valuerow_data['method'] = sheet.cell(i, 6).valuerow_data['url'] = sheet.cell(i, 7).valuerow_data['data'] = sheet.cell(i,8).valuerow_data['expected_code'] = sheet.cell(i, 9).value #预期状态码row_data['actual_code'] = sheet.cell(i, 10).value #实际状态码row_data['response']=sheet.cell(i,11).valuerow_data['auth']=sheet.cell(i,13).valuerow_data['file']=sheet.cell(i,14).valuetest_data.append((row_data))return test_data#写入Excel方法def write_back(self,filename,sheet_name,i,k,value):#i为写入的行k为写入的列wb=load_workbook(filename)sheet=wb[sheet_name]sheet.cell(i,k).value=value#写入表格第14列wb.save(filename)if __name__ == '__main__':test_data=DoExcel().get_data("D:/接口实战/接口自动化用例.xlsx",'storm')# print(test_data)DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx",'storm',2,5)

封装请求方法

对请求方法进行封装,通过传入的方法,来调用对于的request方法

#封装请求,让代码更简洁,更具有可读性,并且更好维护
import requests
from  common.logger import write_log
class HttpReq(object):"""利用requests封装get请求和post请求需要传递的参数"""def __init__(self):self.headers = {"Content-Type": "application/json",# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36" 伪装user-agent}@staticmethoddef http_request(url,data, http_method, headers=None, cookies=None, auth=None, file=None):try:if http_method.upper() == "GET":res = requests.get(url, data=data, headers=headers, cookies=cookies, auth=auth, files=file)return reselif http_method.upper() == "POST":res = requests.post(url, data=data, headers=headers, cookies=cookies, auth=auth, files=file)return reselse:# print("输入的请求方法不对")write_log.info("输入的请求方法不对")except Exception as e:# print("请求报错了:{0}".format(e))write_log.error("请求报错了:{0}".format(e))raise eETReq = HttpReq()

日志模块

本模块用来生成执行测试用例时产生的日志

import logging
import os
from logging import handlers
from config.ProjectConfig import ETConfigdef logger():# os.makedirs("{}logs".format(ETConfig.Log_DIR), exist_ok=True)#os.makedirs() 方法用于递归创建目录。log = logging.getLogger("{}\\et.log".format(ETConfig.Log_DIR))format_str = logging.Formatter('%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s', '%Y-%m-%d %H:%M:%S')# 按天录入日志,最多保存7天的日志handler = handlers.TimedRotatingFileHandler(filename=("{}/et.log".format(ETConfig.Log_DIR)), when='D', backupCount=7, encoding='utf-8')log.addHandler(handler)log.setLevel(logging.INFO)handler.setFormatter(format_str)return logwrite_log = logger()
write_log.info("你好")

发送邮件

本模块实现发送邮件功能,通过附件将html报告发送给对应的邮箱。

from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from config.ProjectConfig import ETConfig
from common.logger import write_log
import smtplib
import time
class sendEmail:# 发送邮件函数def send_mail(self):"""发送邮件:return:"""# 打开报告文件# 邮箱信息self.smtpserver = ETConfig.EMAIL_CONFIG['EMAIL_SERVER']self.user = ETConfig.EMAIL_CONFIG['EMAIL_USER']self.password = ETConfig.EMAIL_CONFIG['EMAIL_PWD']self.sender = ETConfig.EMAIL_CONFIG['EMAIL_SENDER']self.receiver = ETConfig.EMAIL_CONFIG['EMAIL_RECEIVER']self.report_dir=ETConfig.Report_DIR# # html报告路径# self.report_dir = "{}report".format((ETConfig.Report_DIR))with open('{}\\et_result.html'.format(self.report_dir), 'rb') as f:mail_body = str(f.read(), encoding="utf-8")msg = MIMEMultipart('mixed')msg_html = MIMEText(mail_body, 'html', 'utf-8')msg_html["Content-Disposition"] = 'attachment; filename="TestReport.html"'msg.attach(msg_html)msg_html1 = MIMEText(mail_body, 'html', 'utf-8')msg.attach(msg_html1)#附件msg['Subject'] = u'自动化测试报告 {}'.format(time.strftime("%Y-%m-%d", time.localtime()))msg['From'] = u'AutoTest <%s>' % self.sendermsg['To'] = self.receiver# msg['Cc'] = self.cctry:smtp = smtplib.SMTP()smtp.connect(self.smtpserver)smtp.login(self.user, self.password)smtp.sendmail(self.sender, self.receiver, msg.as_string())smtp.quit()write_log.info("发送邮件成功!")except Exception as e:write_log.error("发送邮件失败:{}".format(e))

封装配置

ProjectConfig.py用来对项目用到的配置进行进行封装。

import os
class ProjectConfig(object):
#封装配置version="v1.0"url="XXX"
# 替换为你本地的接口项目路径(注意不是自动化项目路径)PROJECT_DIR = "C:\\Users\\010702\\PycharmProjects\\easytest\\接口环境\\"# 自动化测试项目目录TEST_DIR = "D:\APItest"Log_DIR="D:\\APItest\\log"Report_DIR="D:\\APItest\\report"
#邮件配置信息EMAIL_CONFIG={"EMAIL_SERVER":"smtp.qq.com",#服务器"EMAIL_USER":"XXX","EMAIL_PWD":"XXXXXXmdhje",#授权码"EMAIL_SENDER":"XXX","EMAIL_RECEIVER":"XXX"}
ETConfig=ProjectConfig()

测试用例模块

getUserStorm.py测试用例文件。


#storm项目获取用户信息 DDT+Excel Excel有几条数据,就执行几次用例
import unittest
import requests
import json
from config.ProjectConfig import ETConfig
from testcase.data.DepartmentData import ADD_DATA
from ddt import ddt,data,unpack
from common.wrapers import *
#这里竟然可以只导入一个对象
from common.HttpReq import ETReq
from common.doExcel import DoExcel
from common.HttpReq import HttpReq
from common.is_json import IsJson
from common.logger import write_log
import warnings
@ddt
class GetUserTest(unittest.TestCase):test_data = DoExcel().get_data("D:/接口实战/接口自动化用例.xlsx", 'getuser')#只要哪一行有值,就会被读为一条用例@classmethoddef setUpClass(cls):write_log.info("------------------")"""获取用户信息"""def setUp(self):warnings.simplefilter('ignore',ResourceWarning)def tearDown(self):pass@write_case_log()@data(*test_data)def test_get_user_info(self,item):print("正在执行测试用例{0}".format(item['title']))r=HttpReq().http_request(url=item['url'],data=(item['data']),http_method=item['method'])# print("响应文本为:"+r.text)try:self.assertEqual(item['expected_code'], r.json()['code'])  # 预期结果和直接返回的状态码比较TestResult='PASS'# print("测试用例执行成功")write_log.info("测试用例执行成功")except AssertionError as e:TestResult='FAIL'# print("执行用例出错(0)".format(e))write_log.error("执行用例出错{0}".format(e))raise efinally:DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx", 'getuser',item['case_id']+1,10,r.json()['code'])DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx", 'getuser',item['case_id']+1,11,r.text)DoExcel().write_back("D:/接口实战/接口自动化用例.xlsx", 'getuser',item['case_id']+1,12,TestResult)#写入结果# r=IsJson(r)# self.assertEqual(item['expected'],r['code'])#结果和响应结果中的code边角if __name__ == '__main__':# unittest.main()suite=unittest.TestSuite()suite.addTest(GetUserTest("test_get_user_info"))# suite.addTest(AddDepartmentTest("test_add_department_2"))runner=unittest.TextTestResult()test_result=runner.run(suite)

执行用例

run.py用来执行用例,并生成测试报告。

import unittest
import platform
import os.path
from common.logger import write_log
from config.ProjectConfig import ETConfig
from common.HTMLTestRunnerCNs import HTMLTestRunner
from common.send_email import sendEmail
class RunCase(object):report_dir=ETConfig.Report_DIR#执行用例函数def run_case(self):# 运行测试用例并生成html测试报告with open('{}//et_result.html'.format(self.report_dir), 'wb') as fp:try:write_log.info("RunCase执行用例--开始")suite = unittest.TestSuite()tests = unittest.defaultTestLoader.discover('..\\testcase', pattern='*Storm.py')suite.addTest(tests)runner = HTMLTestRunner(stream=fp, title=u'自动化测试报告', description=u'运行环境:{}'.format(platform.platform()),tester="istester")runner.run(suite)write_log.info("RunCase执行用例--结束")except Exception as e:write_log.error("RunCase执行用例,生成报告失败:{}".format(e))if __name__ == '__main__':test = RunCase()#创建对象test.run_case()#调用测试用例执行函数sendEmail().send_mail()#调用发送邮件函数

测试报告

源码:https://github.com/2504973175/API_test.git


http://chatgpt.dhexx.cn/article/IbGRweYv.shtml

相关文章

基于 python 的接口自动化测试,让你轻松掌握接口自动化

目录 目录 一、简介 ​编辑二、引言 三、环境准备 四、测试接口准备 接口信息 五、编写接口测试 六、优化 封装接口调用 一、简介 本文从一个简单的登录接口测试入手&#xff0c;一步步调整优化接口调用姿势&#xff1b; 然后简单讨论了一下接口测试框架的要点&#xff…

接口自动化测试工程化——了解接口测试

什么是接口测试 接口测试也是一种功能测试 我理解的接口测试&#xff0c;其实也是一种功能测试&#xff0c;只是平时大家说的功能测试更多代指 UI 层面的功能测试&#xff0c;而接口测试更偏向于服务端层面的功能测试。 接口测试的目的 测试左移&#xff0c;尽早介入测试&#…

接口自动化测试【完整版】

1. 什么是接口测试 顾名思义&#xff0c;接口测试是对系统或组件之间的接口进行测试&#xff0c;主要是校验数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型&#xff0c;测试类型又主…

接口自动化测试

接口自动化测试 1.基础知识1.接口测试原理2.接口测试点及用例设计方法3.接口测试要点4.常见HTTP状态码5.HTTP基础知识6.接口自动化测试工具7.token 2.抓包工具1.chrom抓包2.Fiddler抓包&#xff08;PC端&#xff0c;手机端&#xff09;1.原理2.下载安装3.抓取数据信息说明&…

接口自动化测试(Python+Requests+Unittest)

(1)接口自动化测试的意义、前后端分离思想 接口自动化测试的优缺点&#xff1a; 优点&#xff1a; 测试复用性。 维护成本相对UI自动化低一些。 为什么UI自动化维护成本更高&#xff1f; 因为前端页面变化太快&#xff0c;而且UI自动化比较耗时&#xff08;比如等待页面元素的…

接口自动化测试,一看就会

引言 与UI相比&#xff0c;接口一旦研发完成&#xff0c;通常变更或重构的频率和幅度相对较小。因此做接口自动化的性价比更高&#xff0c;通常运用于迭代版本上线前的回归测试中。 手工做接口测试&#xff0c;测试数据和参数都可以由测试人员手动填写和更新。 因此我们在考…

Pytorch损失函数(nn.L1Loss、nn.SmoothL1Loss、nn.MSELoss 、nn.CrossEntropyLoss、nn.NLLLoss)

文章目录 nn.L1Lossnn.SmoothL1Lossnn.MSELossnn.CrossEntropyLossnn.NLLLoss 损失函数&#xff0c;是编译一个神经网络模型必须的两个参数之一&#xff0c;另一个是优化器。损失函数是指用于计算标签值和预测值之间差异的函数&#xff0c;常见的有多种损失函数可供选择&#x…

链表L->next

2020/10/26更新 #include <iostream> using namespace std;struct MyStruct {int data 0;MyStruct* next; }; int main() {MyStruct* L;MyStruct head ,firstNode;head.data 1;firstNode.data 2;head.next &firstNode;L &head;cout << L->next-&g…

L多样化

为了解决同质性攻击和背景知识攻击所带来的隐私泄露&#xff0c;Machanavajjhala等人提出了L-多样性(l-diversity)模型。简单来说&#xff0c;就是在公开的数据中&#xff0c;每一个等价类里的敏感属性必须具有多样性&#xff0c;即L-多样性保证每一个等价类里&#xff0c;敏感…

L'Hospital法则

1.LHospital法则利用柯西中值定理证明 2.该法则适用f与g同时为无穷小量或g为无穷大量的情况 3.注意该法则只给出了充分不必要条件 今天我们介绍一种函数求极限的方法——LHospital法则。它主要用在求解"待定型"极限 1 首先阐述定理: 我们证明这个定理: 微分中值定理…

李沐老师 d2l库画图在 pycharm 动态显示问题(已解决)

修改 d2l.Animator 类的部分代码 1. 在 Animator 类中的 add() 方法中添加两行代码 plt.draw() plt.pause(0.001) 2. 在 Animator 添加 show() 方法 def show(self):display.display(self.fig) 3. 在需要显示的时候调用 animator.show() 结果

L298N——真正的玄学驱动板

总结 L298N 电机就是不转问题&#xff01;&#xff01;&#xff01; 目录 前言 1、共地问题 PWM 不能直接控制电机转动&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;别把PWM直接接电机&#xff01;&…

QMC5883L说明文档

个人博客&#xff1a;http://brainware360.cn/ QMC5883L源于Honeywell的HMC5883L&#xff0c;是一款表面贴装的集成了信号处理电路的三轴磁性传感器&#xff0c;应用场景主要包括罗盘、导航、无人机、机器人和手持设备等一些高精度的场合。 外形如下图所示&#xff1a; Figur…

安装 d2l

1.下载whl &#xff1a;https://www.cnpython.com/pypi/d2l/download 下载后放在哪个目录下都行 2.切换到刚刚下载的这个文件的所在目录&#xff0c;打开cmd 3.如上图标示&#xff0c;打开cmd&#xff0c;在cmd窗口中输入安装命令&#xff1a;pip install whl文件的名字 4.…

L298n

一时兴起&#xff0c;把之前的东西整一下。L298N资料&#xff08;非原创&#xff0c;贴出来便于日后查阅&#xff0c;或许能给给初学者一点帮助&#xff09;

L9110电机驱动电路

我需要设计一个驱动电路去驱动这样一个电机。电机的两个端子的输入波形如图&#xff1a; 驱动的波形为50%占空比的方波&#xff0c;频率为5Hz&#xff0c;额定电压12V。 单片机IO口可以输出3.3V/5V的PWM波&#xff0c;不过电压不够&#xff0c;驱动能力也不够&#xff0c;电机…

canon l11121e驱动_佳能L11121e驱动

佳能L11121e驱动可以帮助用户解决同型号打印机无法被电脑识别或者打印异常的问题&#xff0c;如果你在使用该型号打印机时遇到了上述问题&#xff0c;可以来本站下载使用该驱动&#xff0c;正确安装一下即可解决问题&#xff0c;让打印机恢复正常工作&#xff01; 佳能L11121e驱…

A2L文件介绍

文章目录 一、概述二、图2中不同块的意义如下&#xff1a;三、 A2L块示例补充知识参考文章 一、概述 A2L文件定义了标定过程中&#xff0c;上位机与ECU之间的通信所需的信息&#xff0c;可以是XCPonCAN&#xff0c;XCPonUSB、XCPonSPI等。 A2L标准分为三个部分&#xff0c;分别…

目标检测:损失函数之SmoothL1Loss

fasterRCNN中的RPN的回归框的loss计算方法 再次深入的解读SmoothL1Loss损失函数&#xff1a; fasterRCNN中SmoothL1Loss的详解

s905l android5,魔百盒CM201-1-YS-S905L纯净安卓系统固件包

魔百盒CM201-1-YS-S905L纯净安卓系统固件包是一个魔百盒易视腾YS代工魔百盒cm201-1免拆线刷固件系统纯净包&#xff0c;盒子是广东移动宽带定制的&#xff0c;其他地方只要硬件相同&#xff0c;应该也能够。不过还是提醒一句&#xff0c;刷机有风险&#xff0c;动手需谨慎。 固…