从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)
目录:导读
- 前言
- 一、Python编程入门到精通
- 二、接口自动化项目实战
- 三、Web自动化项目实战
- 四、App自动化项目实战
- 五、一线大厂简历
- 六、测试开发DevOps体系
- 七、常用自动化测试工具
- 八、JMeter性能测试
- 九、总结(尾部小惊喜)
前言
接口测试是对系统和组件之间的接口进行测试,主要是效验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,RPC,Webservice,Dubbo,RESTful等类型。
接口测试流程
1、需求评审,熟悉业务和需求
2、开发提供接口文档
3、编写接口测试用例
4、用例评审
5、提测后开始测试
6、提交测试报告
两种常见的 HTTP 请求方法:GET 和 POST
框架是一套基于Python+Pytest+Requests+Allure+Jenkins而设计的数据驱动接口自动化测试的框架。
技术栈:
Python、Pytest、Requests、Pactverity、Excel、Json、Mysql、Allure、Logbook、Git、Jenkins
框架结构图:

项目功能:
Python+Pytest+Allure+Jenkins接口自动化框架,实现Excel或Json维护测试用例,支持数据库操作,利用封装的请求基类调取相应的测试用例接口,获取配置文件中的环境地址与环境变量,
结合Pytest进行单元测试,使用LogBook进行记录日志,并生成allure测试报告,最后进行Jenkins集成项目实现集成部署,并发送测试报告邮件。
工具类封装
1、日志模块
项目中的log日志是logbook进行日志记录的,方便测试开发调试时进行排错纠正或修复优化。日志可选择是否打印在屏幕上即运行时是否在终端输出打印。日志格式输出可调整。
handle_log.py部分源码
def log_type(record, handler):log = "[{date}] [{level}] [{filename}] [{func_name}] [{lineno}] {msg}".format(date=record.time, # 日志时间level=record.level_name, # 日志等级filename=os.path.split(record.filename)[-1], # 文件名func_name=record.func_name, # 函数名lineno=record.lineno, # 行号msg=record.message # 日志内容)return log# 日志存放路径LOG_DIR = BasePath + '/log'print(LOG_DIR)if not os.path.exists(LOG_DIR):os.makedirs(LOG_DIR)# 日志打印到屏幕log_std = ColorizedStderrHandler(bubble=True)log_std.formatter = log_type# 日志打印到文件log_file = TimedRotatingFileHandler(os.path.join(LOG_DIR, '%s.log' % 'log'), date_format='%Y-%m-%d', bubble=True, encoding='utf-8')log_file.formatter = log_type# 脚本日志run_log = Logger("global_log")def init_logger():logbook.set_datetime_format("local")run_log.handlers = []run_log.handlers.append(log_file)run_log.handlers.append(log_std)return ""
打印在终端的日志,如下图所示。

同时运行项目后,会在项目文件log中自动生成一个以当天日期命名的log文件。点击log日志文件可查看日志详情即项目运行时所记录的日志或报错日志。如下图所示。

2、配置文件模块
项目中涉及到一些配置文件如username、password或环境变量时,我们可通过配置文件来获取配置值。通过配置文件中key与value的定义来确定获取配置文件的值。
handle_init.py部分源码
class HandleInit:# 读取配置文件def load_ini(self):file_path = BasePath + "/config/config.ini"cf = configparser.ConfigParser()cf.read(file_path, encoding='UTF-8')return cf# 获取ini里面对应key的valuedef get_value(self, key, node=None):if node == None:node = 'Test'cf = self.load_ini()try:data = cf.get(node, key)logger.info('获取配置文件的值,node:{},key:{}, data:{}'.format(node, key, data))except Exception:logger.exception('没有获取到对应的值,node:{},key:{}'.format(node, key))data = Nonereturn data
获取配置文件中的值日志如下图所示。

3、接口请求封装
获取相关测试用例及接口用例配置,记录请求相关参数的日志,定义Allure测试报告的步骤。
handle_apirequest.py部分代码
class ApiRequest:def api_request(self, base_url, test_case_data, case_data):get_name = Noneget_url = Noneget_method = Noneget_headers = Noneget_cookies = Noneget_case_name = Noneget_case_params = Noneresponse_data = Nonetry:get_name = test_case_data['config']['name']get_url = base_url + test_case_data['config']['url']get_method = test_case_data['config']['method']get_headers = test_case_data['config']['headers']get_cookies = test_case_data['config']['cookies']except Exception as e:logger.exception('获取用例基本信息失败,{}'.format(e))try:get_case_name = case_data['name']get_case_params = case_data['params']except Exception as e:logger.exception('获取测试用例信息失败,{}'.format(e))with allure.step("请求接口:%s,请求地址:%s,请求方法:%s,请求头:%s,请求Cookies:%s" % (get_name, get_url, get_method, get_headers, get_cookies)):allure.attach("接口用例描述:", "{0}".format(get_case_name))allure.attach("接口用例请求参数:", "{0}".format(get_case_params))logger.info('请求接口名:%r,请求地址:%r,请求方法:%r,请求头:%r,请求Cookies:%r' %\ (get_name, get_url, get_method, get_headers, get_cookies))logger.info('请求接口名:%r,请求接口用例名:%r,接口用例请求参数:%r' %\(get_name, get_case_name, get_case_params))try:response_data = baseRequest.run_main(get_method, get_url, get_case_params, get_headers)except Exception as e:logger.exception('用例请求返回失败,{}'.format(e))logger.info('请求接口名:%r,请求接口用例名:%r,返回参数:%r' % (get_name, get_case_name, response_data.json()))return response_data
4、Excel数据处理-测试用例

测试用例中维护在Excel文件中,类中定义如何获取Excel中的相关数据(如获取某个单元格的内容,获取单元格的行数,以及将数据写入Excel中等操作)。
handle_exceldata.py部分源码
class OperationExcel:def __init__(self, file_name=None, sheet_id=None):if file_name:self.file_name = file_nameself.sheet_id = sheet_idelse:self.file_name = ''self.sheet_id = 0self.data = self.get_data()# 获取sheets的内容def get_data(self):data = xlrd.open_workbook(self.file_name)tables = data.sheets()[self.sheet_id]return tables# 获取单元格的行数def get_lines(self):tables = self.datareturn tables.nrows# 获取某一个单元格的内容def get_cell_value(self, row, col):return self.data.cell_value(row, col)
5、JSON数据处理-测试用例
{"config":{"name":"post接口名","url":"/langdetect","method":"POST","headers":{"Content-Type":"application/json"},"cookies":{}},"testcase":[{"name":"测试用例1","params":{"query":"测试"},"validate":[{"check":"status_code","comparator":"eq","expect":"200"}]},{"name":"测试用例2","params":{"query":"python"},"validate":[{"check":"msg","comparator":"eq","expect":"success"}]}]
}
获取Json文件中里具体字段的值。
handle.json.py部分源码
class HandleJson:# 读取json文件def load_json(self, file_name):if file_name == None:file_path = ""else:file_path = file_nametry:with open(file_path, encoding='UTF-8') as f:data = json.load(f)return dataexcept Exception:print("未找到json文件")return {}# 读取json文件里具体的字段值def getJson_value(self, key, file_name):if file_name == None:return ""jsonData = self.load_json(file_name)if key == None:getJsonValue = ""else:getJsonValue = jsonData.get(key)return getJsonValue
基类封装
接口支持Get、Post请求,调用requests请求来实现接口的调用与返回。接口参数包括,接口地址、接口请求参数、cookie参数、header参数。
class BaseRequest:def send_get(self, url, data, header=None, cookie=None):"""Requests发送Get请求:param url:请求地址:param data:Get请求参数:param cookie:cookie参数:param header:header参数"""response = requests.get(url=url, params=data, cookies=cookie, headers=header)return responsedef send_post(self, url, data, header=None, cookie=None):"""Requests发送Post请求:param url:请求地址:param data:Post请求参数:param data:Post请求参数:param cookie:cookie参数:param header:header参数"""response = requests.post(url=url, json=data, cookies=cookie, headers=header)return response# 主函数调用def run_main(self, method, url, data, header, cookie=None):try:result = ''if method.upper() == 'GET':result = self.send_get(url, data, header, cookie)elif method.upper() == 'POST':result = self.send_post(url, data, header, cookie)return resultexcept Exception as e:logger.exception('请求主函数调用失败:{}'.format(e))
测试用例编写
引用Pytest来进行接口的单元测试,通过JSON中多个测试用例来做为参数化数据驱动。结合Allure制定相应接口的测试报告。在接口返回断言之前,我们先进行该接口的契约测试,
我们采用的是Pactverity的全量契约校验测试。当契约测试通过时,我们再进行返回参数的相关校验测试。
test_getRequestJson.py部分源码
@allure.feature('测试GET请求模块')
class TestRequestOne():@allure.title('测试标题')@allure.testcase('测试地址:https://www.imooc.com')@pytest.mark.parametrize('case_data', testCaseData['testcase'])def test_requestOne(self, case_data):try:api_response = apiRequest.api_request(baseurl, testCaseData, case_data)api_response_data = api_response.json()# pactverity——全量契约校验config_contract_format = Like({"msg": "成功","result": 0,"data": EachLike({"word": Like("testng")})})mPactVerify = PactVerify(config_contract_format)try:mPactVerify.verify(api_response_data)logger.info('verify_result:{},verify_info:{}'.format(mPactVerify.verify_result, mPactVerify.verify_info))assert mPactVerify.verify_result == Trueexcept Exception:err_msg = '契约校验错误'logger.exception('测试用例契约校验失败,verify_result:{},verify_info:{}'.format(mPactVerify.verify_result,mPactVerify.verify_info))try:for case_validate in case_data['validate']:logger.info('断言期望相关参数:check:{},comparator:{},expect:{}'.format(case_validate['check'],case_validate['comparator'],case_validate['expect']))comparatorsTest.comparators_Assert(api_response, case_validate['check'],case_validate['comparator'], case_validate['expect'])logger.info('测试用例断言成功')except Exception as e:logger.exception('测试用例断言失败')except Exception as e:logger.exception('测试用例请求失败,原因:{}'.format(e))
主运行:
运用Pytest和Allure的特性,命令行运行测试用例文件夹,并生成对应的allure测试报告。
if __name__ == "__main__":pytest.main(['-s', '-v', 'test_case/testRequest/', '-q', '--alluredir', 'reports'])
Alluer2 测试报告
当我们运行主函数时,并生成对应的测试用例报告时,我们可以看到在该文件夹中会生成对应的json文件的测试报告。
reports是json格式测试报告存放的目录位置,allure_reports是html测试报告文件生成的目录位置。allure命令如下。
allure generate reports -o allure_result/
项目根目录下的allure_reports文件,存放的是allure生成的测试报告。可看出文件下有一个HTML文件,可通过Python的编辑器Pycharm来打开该HTML文件(测试报告),或可通过allure命令来打开该HTML。
| 下面是我整理的2023年最全的软件测试工程师学习知识架构体系图 |
一、Python编程入门到精通

二、接口自动化项目实战

三、Web自动化项目实战

四、App自动化项目实战

五、一线大厂简历

六、测试开发DevOps体系

七、常用自动化测试工具

八、JMeter性能测试

九、总结(尾部小惊喜)
勇攀高峰,永不言弃,奋斗的旅程犹如绽放的花朵;跨越征程,超越极限,拼搏的力量铸就辉煌的人生。相信自己的潜能,释放内心的火焰,用汗水和努力砥砺出属于自己的辉煌之路。
披荆斩棘,破浪前行,奋斗是人生最壮丽的交响乐;勇往直前,超越极限,梦想是心灵最美的翅膀。相信坚持,追逐光芒,奋斗点亮未来的星空,谱写属于自己的辉煌篇章。
不畏艰辛,奋斗向前,执着追寻心中的星辰大海;拥抱挑战,超越极限,每一次努力都是成长的脚印。相信自己的力量,燃烧激情,创造出属于自己的辉煌人生。
相关文章:
从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 接口测试是对系统…...
在windows配置redis的一些错误及解决方案
目录 Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException:用客户端Redis Desktop Manager一样的密码端口,是可以正常连接的,但是运行java程序之后使用接口请求就会报错 Unable to connect to Redis; nested e…...
真机搭建中小网络
这是b站上的一个视频,演示了如何搭建一个典型的中小网络,供企业使用 一、上行端口:上行端口就是连接汇聚或者核心层的口,或者是出广域网互联网的口。也可理解成上传数据的端口。 二、下行端口:连接数据线进行下载的端…...
Linux:shell脚本:基础使用(1)
Shell的作用 命令解释器,“翻译官”,介于系统内核与用户之间,负责解释命令行 用户的登录Shell 登录后默认使用的Shell程序,一般为 /bin/bash 不同Shell的内部指令、运行环境等会有所区别 cat /etc/shells 编写第一个Shell脚本 …...
carla中lka实现(一)
前言: 对于之前项目中工作内容进行总结,使用Carla中的车辆进行lka算法调试,整体技术路线: ①在Carla中生成车辆,并在车辆上搭载camera,通过camera采集图像数据; ②使用图像处理lka算法&#…...
常见的数据结构(顺序表、顺序表、链表、栈、队列、二叉树)
线性表(Linear List) 1.什么是线性表 2.线性表的特点 3.线性表的基本运算 顺序表 1.什么是顺序表 2.时间复杂度: 链表 1.什么是链表 2.单向链表 3. 双向链表 4.ArrayList和LinkedList的使用 栈Stack 1.什么是栈 2.栈的基本方法 队列…...
(12)理解委托,反射,Type,EvenInfo,插件, 组合枚举,BindingFlags,扩展方法及重载,XML认识
一、复习委托事件 1、委托复习。 private delegate int MyDelegate(int a, int b); //1.定义委托类型private static void Main(string[] args){MyDelegate md new MyDelegate(AddDelegate);//2.声明委托变量int result md(1, 2);//3.调用委托Console.WriteLine(result);Cons…...
软件建设方案技术方案实施方案密码评测方案等保测评方案人员培训方案项目建设与运行管理项目招标方案模板目录
第一章 项目概述 1.项目名称(包含项目全称和简称) 2.项目建设单位及负责人、项目责任人 3.项目建设依据 (1)政策依据(主要从国家、省、市、行业部门相关的政策文件要求等方面进行描述) (2)技术标准 4.项目建设目标、建设任务 5.项目主要建设内容、规模、建设周期…...
pytorch中torch.einsum函数的详细计算过程图解
第一次见到 rel_h torch.einsum(“bhwc,hkc->bhwk”, r_q, Rh)这行代码时,属实是懵了,网上找了很多博主的介绍,但都没有详细的说明函数内部的计算过程,看得我是一头雾水,只知道计算结果的维度是如何变化的…...
【iOS】App仿写--天气预报
文章目录 前言一、首页二、搜索界面三、添加界面四、浏览界面总结 前言 最近完成了暑假的最后一个任务——天气预报,特此记录博客总结。根据iPhone中天气App的功能大致可以将仿写的App分为四个界面——首页,搜索界面,添加界面,浏…...
快速远程桌面控制公司电脑远程办公
文章目录 第一步第二步第三步 远程办公的概念很早就被提出来,但似乎并没有多少项目普及落实到实际应用层面,至少在前几年,远程办公距离我们仍然很遥远。但2019年末突如其来的疫情,着实打了大家一个措手不及。尽管国内最初的大面积…...
亚信科技AntDB数据库专家出席数据库标准研讨会并参与研讨
2023年7月12日,全国信息技术标准化技术委员会数据库标准工作组(SAC/TC28/WG31)秘书处组织召开数据库标准研讨会,会议围绕数据库标准工作组2023年上半年开展的标准编制情况进行交流。亚信科技AntDB数据库相关专家出席会议ÿ…...
【我们一起60天准备考研算法面试(大全)-第三十四天 34/60】【前缀和】【北邮】
专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示&#…...
【数据分析】numpy (二)
numpy作为数据分析,深度学习常用的库,本篇博客我们来介绍numpy的一些进阶用法: 一,numpy的常用简单内置函数: 1.1求和: a np.array([[1, 2],[3, 4]]) np.sum(a)10 1.2求平均值: np.mean(a…...
Vue3小案例—v-model 双向数据绑定实现动态列表增加和删除
v-model双向绑定的原理: v-model 是Vue.js 提供的一个指令,用于实现双向数据绑定,它可以将表单元素的值与Vue实例的数据绑定在一起,当表单元素的值发生改变时,Vue实例的数据也会随之更新,反之亦然。 …...
MySQL 重置root 密码
5.7 版本 首先要把服务mysql57 关闭 net stop MySQL57 在安装的mysql57的程序的bin中 运行cmd(管理员运行) mysqld --defaults-file‘mysql存放数据的位置\my.ini’ --skip-grant-tables 上图 错误 注意:如果遇到mysqld: Can’t change dir…...
OpenCV图像处理技巧之空间滤波
1. 引言 再次问好,图像处理爱好者们!🌟 在前面的章节中,我们学习了图像处理的基础知识,并展现了图像增强的魅力。在这一节中,我们将更深入地研究空间滤波技术。 闲话少说,我们直接开始吧&#…...
Java超级玛丽小游戏制作过程讲解 第一天 创建窗口
package com.sxt;import javax.swing.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener;public class MyFrame extends JFrame implements KeyListener {//设置窗口的大小为800*600public MyFrame() {this.setSize(800, 600);//设置窗口中显示this.setLo…...
【POP3/IMAP/SMTP】QQ邮箱设置
什么是 POP3/IMAP/SMTP 服务 POP3 (Post Office Protocol - Version 3)协议用于支持使用电子邮件客户端获取并删除在服务器上的电子邮件。 IMAP (Internet Message Access Protocol)协议用于支持使用电子邮件客户端交互式存取服务…...
云计算——常见集群策略
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.什么是集群 二.集群策略 1.虚拟机HA 实现虚拟机高可用性通常涉及以下关键…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
