如此简单,一文带你玩转接口自动化上(Python + Pytest + Requests + Allure )

一. 前言

哈喽大伙们好,好久不见距离上次更新博客已经有一年之久了,这将近一年的时间小编主要的时间都花在了实习和24届校招上面了,最终也是收获满满,选择了一个还不错的offer,感谢一路走来的自己和身边朋友的帮助,在实习期间我也是学习了一套比较适合新手学习的接口子自动化框架,前提是有Python基础,这样理解起来就很简单了,并且这套框架也是在企业中真正的完成了落地,技术栈主要是Python + Pytest + Requests + Allure,往下看吧;

二. 项目框架

1. 项目目录

(1) api

顾名思义,api这个文件夹底下就是存放你要自动化的接口;

拿最简单的登录接口为代码示例:

def login(email, pwd):"""用户登录:param email::param pwd::return:"""json_data = {"email": str(email),"pwd": str(pwd)}# 这里对请求和返回做了二次封装response = api_util.user_login(json=json_data)return process_response(response)

(2) cases

这个文件夹主要存放测试用例

登录接口代码示例:

@allure.title("用户登录")@pytest.mark.parametrize("email,pwd",base_data.read_data()['test_login'])@pytest.mark.run(order=1)def test_login(self,email,pwd):try:result = login(email,pwd)assert result.success is Trueprint(result)# 断言返回的code是否是200assert result.body['code'] == 200except Exception as e:print("异常了",e)

(3) config

这个文件夹主要存放一些配置信息的,比如某些自动化场景我们涉及到查数据库,这里可以存放数据库的配置信息,一般在这个文件下创建一个ini文件,示例:

[host]
url = https://www.baidu.com[mysql]
MYSQL_HOST=x.x.x.x:x
MYSQL_PORT=xxxx
MYSQL_USER=xxxx
MYSQL_PASSWD=xxxx
MYSQL_DB=xxxx

(4) core

这个文件夹下主要是针对接口返回的信息做二次封装,代码示例:

class RestClient:def __init__(self):self.api_root_url = api_root_urlself.session = requests.Session()def get(self, url, **kwargs):return self.request(url, "GET", **kwargs)def post(self, url, **kwargs):return self.request(url, "POST", **kwargs)def put(self, url, **kwargs):return self.request(url, "PUT", **kwargs)def delete(self, url, **kwargs):return self.request(url, "DELETE", **kwargs)def request(self, url, method, **kwargs):self.request_log(url, method, **kwargs)if method == "GET":return self.session.get(self.api_root_url + url, **kwargs)if method == "POST":return self.session.post(self.api_root_url + url, **kwargs)if method == "PUT":return self.session.put(self.api_root_url + url, **kwargs)if method == "DELETE":return self.session.delete(self.api_root_url + url, **kwargs)def request_log(self, url, method, **kwargs):data = dict(**kwargs).get("data")json_data = dict(**kwargs).get("json")params = dict(**kwargs).get("params")headers = dict(**kwargs).get("headers")logger.info("接口请求的地址--> {}".format(self.api_root_url + url))logger.info("接口请求的方法--> {}".format(method))if data is not None:logger.info("接口请求的data参数-->\n{}".format(json.dumps(data, ensure_ascii=False, indent=2)))if json_data is not None:logger.info("接口请求的json参数-->\n{}".format(json.dumps(json_data, ensure_ascii=False, indent=2)))if params is not None:logger.info("接口请求的params参数-->\n{}".format(json.dumps(params, ensure_ascii=False, indent=2)))if headers is not None:logger.info("接口请求的headers参数-->\n{}".format(json.dumps(headers, ensure_ascii=False, indent=2)))

通过二次封装打印在控制台,我们可以很清楚的看到接近请求的地址,方法,参数和返回的body,如图:


(5) data

这个文件下主要存放用户的一些请求参数,比如登录接口所需要的用户名和密码,可以创建一个yaml文件来存放,并且配合Pytest里面的@pytest.mark.parametrize注解去解析yaml文件的数据(此方法一般用于频繁使用参数的时候,好处就是不需要在每个函数下去写请求参数,每次调用只要通过注解去拿数据就好了,视具体业务场景去使用)代码示例:

test_login:- [ 2xxxxxxxxxxx@qq.com,ee587a8b54152ad77d9a4267dd5d99e5 ]
 @allure.title("用户登录")# 读取yaml里面的数据@pytest.mark.parametrize("email,pwd",base_data.read_data()['test_login'])@pytest.mark.run(order=1)def test_login(self,email,pwd):try:result = login(email,pwd)assert result.success is Trueprint(result)# 断言返回的code是否是200assert result.body['code'] == 200except Exception as e:print("异常了",e)

(6) log

这个文件下就是存放每次运行完之后的日志信息,自动生成的文件;


(7) message // TODO

项目和Jenkins结合实现CI/CD,这个文件夹下主要存放通知工作群的代码,比如你可以编写与飞书,钉钉或者企微,通过webhook去连接,将每次自动化的结果定时下发到工作群,后续更新;


(8) report

项目结合Allure生成测试报告,这个文件夹是存放每次输出的测试报告,也是自动生成的文件,截图如下:


(9) utils

这个文件夹写的东西就非常多了,凡是在做自动化的时候需要用到的一些工具,都可以放到这个文件夹下,比如数据库连接,动态获取token,接口返回数据的异常打印,日志打印等等;示例代码:数据库连接和打印日志统一处理:

# 数据库连接
import logging
import pymysqlfrom utils.log_util import logger
from utils.read_data import base_datadata = base_data.read_ini()['mysql']
DB_CONF = {"host": data['MYSQL_HOST'],"port": int(data['MYSQL_PORT']),"user": data['MYSQL_USER'],"password": data['MYSQL_PASSWD'],"db": data['MYSQL_DB']
}class Mysql:def __init__(self):# 建立 mysql 连接self.conn = pymysql.connect(**DB_CONF, autocommit=True)self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)# 释放资源def __del__(self):self.cur.close()self.conn.close()# 查询一条def select_db_one(self, sql):# 获取数据logger.info(f'执行sql:{sql}')self.cur.execute(sql)result = self.cur.fetchone()logger.info(f'sql执行结果:{result}')return result# 查询多条def select_db_all(self, sql):# 获取数据logger.info(f'执行sql:{sql}')self.cur.execute(sql)result = self.cur.fetchall()logger.info(f'执行结果:{result}')return resultdef execute_db(self, sql):# sql 可能会报错,try一下try:logger.info(f'执行sql:{sql}')self.cur.execute(sql)self.conn.commit()except Exception as e:logging.info("sql执行出错{}".format(e))db = Mysql()
if __name__ == '__main__':db = Mysql()# result = db.select_db_one(#     "select code from users_verifycode where mobile = 'xxxxxxx' order by id desc limit 1;")# print(result['code'])
# 日志打印统一处理
import os
import logging
import time# 找到根目录
root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
# print(root_path)
# 和log文件夹进行关联
log_path = os.path.join(root_path, 'log')
# print(log_path)class Logger:def __init__(self):#定义日志位置和文件名self.logname = os.path.join(log_path,"{}.log".format(time.strftime("%Y-%m-%d")))#定义一个日志容器self.logger = logging.getLogger("log")#设置日志打印的级别self.logger.setLevel(logging.DEBUG)#创建日志输入的格式self.formatter = logging.Formatter('[%(asctime)s][%(filename)s %(lineno)d][%(levelname)s]: %(message)s')#创建日志处理器,用来存放日志文件self.filelogger = logging.FileHandler(self.logname, mode='a', encoding="UTF-8")#创建日志处理器,在控制台打印self.console = logging.StreamHandler()#设置控制台打印日志界别self.console.setLevel(logging.DEBUG)#文件存放日志级别self.filelogger.setLevel(logging.DEBUG)#文件存放日志格式self.filelogger.setFormatter(self.formatter)#控制台打印日志格式self.console.setFormatter(self.formatter)#将日志输出渠道添加到日志收集器中self.logger.addHandler(self.filelogger)self.logger.addHandler(self.console)logger = Logger().loggerif __name__ == '__main__':logger.info("--测试开始--")logger.debug("--测试结束--")

 三. 总结

整体下来这个框架通俗易懂,其实真正在做自动化的时候我们只需要对用例的脚本进行编写就行了,我会附上自己的代码仓库地址,大伙可以拉下来看看,自己尝试实践一下,遇到啥问题可以私信我看到随时解答,关于第二篇就是主要去说下如何通过Git+Linux+Jenkins去部署项目,从而达到一个CI/CD的流水线工作流程,本文欢迎技术大佬指点相互学习,期待下次相遇~

项目地址:pytest: 从0到1搭建接口自动化框架

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/845068.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Three.js实现的3D立方体动画

本文由ScriptEcho平台提供技术支持 项目地址:传送门 基于Three.js实现的3D立方体动画 应用场景 该代码段适用于需要在网页中创建交互式3D场景的场景。例如,可以用于展示产品、创建游戏或制作视觉效果。 基本功能 此代码段使用Three.js库创建了一个…

【机器学习】随机森林:深度解析与应用实践

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 随机森林:深度解析与应用实践引言1. 随机森林基础1.1 什么是随机森林…

Android更新优化 - 增量更新是如何节省用户时间和流量的

增量更新和全量更新 我想玩过大型手游的人都知道,手游的安装包非常大,因为资源图片众多。而你每次更新都把所有文件都更新下来,是非常耗时的,对吧。耗时是一个方面,有些人在户外开的是移动网络,动不动就几…

计算机组成原理·海明编码及其实验

前言:海明编码这一块在刚开始的时候没有弄懂,后面通过做实验、复习慢慢摸清了门道。在学习计算机组成原理的过程中,实验实践是很重要的,它会让你去搞清楚事情背后的原理,逼着你学会你没听懂的东西。这篇文章会从海明码…

Check Point 安全网关任意文件读取漏洞复现(CVE-2024-24919)

Check Point 安全网关任意文件读取漏洞复现(CVE-2024-24919) 1.漏洞描述 Check Point Security Gateways 是 Check Point Sofware 提供的一系列 网络安全Q解决方案。这些解决方案包括下一代防火墙(NGFW)、数据中心安全网关和 A1驱动的量子网关,旨在为企业提供针对…

@Value 读取环境变量配置

在项目开发过程中,有必要使用一些灰色规则(即仅用于开发使用过程中的逻辑控制变量)。 比如,本地开发中,一些业务逻辑需要调用第三方代码,但又在本地调不通,怎么办。只能通过 if(本地开发) {mock…

【开源】渔具租赁系统 JAVA+Vue.js+SpringBoot+MySQL

目录 一、项目介绍 1.1渔具档案模块 1.2渔具租赁模块 1.3渔具归还模块 1.4在线留言模块 二、项目截图 三、核心代码 一、项目介绍 Vue.jsSpringBoot前后端分离新手入门项目《渔具租赁系统》,包括渔具档案模块、渔具租赁模块、渔具归还模块、在线留言模块和部…

当新媒体运营开始说真话,这些道理你真的懂么?沈阳新媒体运营培训

运营新人,尤其是刚毕业、啥都不会的大学生,一定要认清的现实就是:虽然新媒体运营这个岗位门槛比较低,薪资也比较香,但绝不是养老型的工作。 平时大家还是很忙的,所以一定要摒弃学生思维,千万别…

02--nginx代理缓存

前言:比较常用的用法反向代理,和缓存的一些操作,用虚拟环境复刻出来,里面参数不用详细记录,用作复习,使用时直接查找即可。环境搭建过程参考前一篇文章nginx基础。 1、基础环境 IP角色作用192.168.189.143…

freertos初体验 - 在stm32上移植

1. 说明 freertos内核 非常精简,代码量也很少,官方也针对主流的编译器和内核准备好了移植文件,所以 freertos 的移植是非常简单的,很多工具(例如CubeMX)点点鼠标就可以生成一个 freertos 的工程&#xff0…

AquaCrop农业水资源管理,模拟作物生长过程中水分的需求与消耗

AquaCrop是由世界粮食及农业组织(FAO)开发的一个先进模型,旨在研究和优化农作物的水分生产效率。这个模型在全球范围内被广泛应用于农业水管理,特别是在制定农作物灌溉计划和应对水资源限制方面显示出其强大的实用性。AquaCrop 不…

VR导航的实现原理、技术优势和应用场景

VR导航通过虚拟现实技术提供沉浸式环境,结合室内定位技术实现精准导航。目前,VR导航已在多个领域展现出其独特的价值和潜力,预示着智能导航系统的未来发展。 一、实现原理 VR导航技术依托于虚拟现实(VR)和室内定位系统。VR技术利用计算机模…

Python考试复习---day5

1.打印商品名 ainput().split() print("商品列表:") for i,name in enumerate(a):print("{}\t{}".format(i,name))enumerate----枚举--利用它可以同时获得索引和值 enumerate多用于在for循环中得到计数 例如: list1 ["这&qu…

Netty SSL双向验证

Netty SSL双向验证 1. 环境说明2. 生成证书2.1. 创建根证书 密钥证书2.2. 生成请求证书密钥2.3. 生成csr请求证书2.4. ca证书对server.csr、client.csr签发生成x509证书2.5. 请求证书PKCS#8编码2.6. 输出文件 3. Java代码3.1. Server端3.2. Client端3.3. 证书存放 4. 运行效果4…

消费者组到底是什么?no.15

Kafka的消费者组。 消费者组,即Consumer Group,应该算是Kafka比较有亮点的设计了。那么何谓Consumer Group呢?用一句话概括就是:Consumer Group是Kafka提供的可扩展且具有容错性的消费者机制。既然是一个组,那么组内必…

JavaScript 贪心算法(Greedy Algo)

贪婪是一种算法范式,它逐步构建解决方案,始终选择提供最明显和直接收益的下一个部分。贪婪算法用于解决优化问题。 如果问题具有以下属性,则可以使用贪心法解决优化问题: 每一步,我们都可以做出当前看来最好的选择&…

路由器的工作原理

5.1路由器的工作原理 如图5-1所示配置IP地址(此处省略,请读者自行配置),配置完成后,我们在R1上分别ping 12.1.1.2 、23.1.1.2、23.1.1.3,我们可以发现,在R1上ping 12.1.1.2可以通,但…

光电耦合器:航天航空领域的先进连接技术

光电耦合器作为一种关键的电子连接器,在航天航空领域扮演着重要角色。本文将深入探讨光电耦合器在航天航空领域的应用及其技术特点。 光电耦合器在航天航空领域的应用 光电耦合器作为一种高可靠性、高速传输、抗干扰能力强的连接器,在航天航空领域有着广…

释放视频潜力:Topaz Video AI for mac/win 一款全新的视频增强与修复利器

在数字时代,视频已经成为我们记录生活、分享经历的重要方式。然而,有时候我们所拍摄的视频可能并不完美,可能存在模糊、噪点、抖动等问题。这时候,就需要一款强大的视频增强和修复工具来帮助我们提升视频质量,让它们更…

MT8781安卓核心板_MTK联发科Helio G99核心板规格参数

MT8781安卓核心板采用先进的台积电6纳米级芯片生产工艺,配备高性能Arm Cortex-A76处理器和Arm Mali G57 GPU,加上LPDDR4X内存和UFS 2.2存储,在处理速度和数据访问速度上都有着出色的表现。 MT8781还支持120Hz显示器,无需额外的DSC…