如此简单,一文带你玩转接口自动化上(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…

JavaScript基础知识1(引入方式、注释、输入输出、变量、数组)

JavaScript基础知识1(引入方式、注释、输入输出、变量、数组) javascript 引入方式内部方式外部形式 注释和结束符单行注释多行注释 结束符 输入和输出输出输入 alert(你好JS);document.write(js我来了);console.log(看看对不对);prompt(输入您的姓名&am…

cxgrid列内容居中

笑掉大牙,需要这个功能了,找遍了全网,没有一个可用的成功案例,唯一可用的就是表中添加字段,然后选择properties然后选择对齐方式,根本不实用,因为列都是动态生成的,不可能提前做好所…

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

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

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

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

【数据分析】打造完美数据分析环境:Python开发环境搭建全攻略

打造完美数据分析环境:Python开发环境搭建全攻略 在数据分析的世界中,搭建一个稳定且高效的Python开发环境是至关重要的。本文将介绍三种主要的环境搭建方式:使用pip、Anaconda和Miniconda。 1. 使用pip从清华镜像安装Python包 pip是Pytho…

02--nginx代理缓存

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

编译安装gcc-11及可能遇到的bug

编译安装脚本 GCC_VERSION11.1.0 PACKAGE_DIR/path/to/gcc/source/code GCC_DIR$PACKAGE_DIR/gcc-$GCC_VERSION GCC_INSTALL_DIR/path/to/install/gccmkdir -p $GCC_INSTALL_DIR cd $GCC_INSTALL_DIR rm -rf * cd $PACKAGE_DIR rm -rf gcc-$GCC_VERSION if [ ! -f "gcc-$…

freertos初体验 - 在stm32上移植

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

ubuntu18.04安装pycharm2024.1.2后,创建快捷方式图标

Ubuntu 18.04 安装 PyCharm并创建快捷方式_untuntu018.04 pycharm怎么创建快捷方式-CSDN博客

探秘Spring Bean之单例奥秘:源码深析与高级应用

1. 引言 在Spring框架中,Bean的作用域是控制Bean实例创建和管理的重要概念。深入理解Bean的作用域,尤其是单例作用域(Singleton),对于优化系统性能、提升线程安全性以及管理资源等方面具有至关重要的作用。本文将围绕…

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…