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

news2024/11/24 16:30:36

一. 前言

哈喽大伙们好,好久不见距离上次更新博客已经有一年之久了,这将近一年的时间小编主要的时间都花在了实习和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 True
            print(result)
            # 断言返回的code是否是200
            assert result.body['code'] == 200
        except 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_url
        self.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 True
            print(result)
            # 断言返回的code是否是200
            assert result.body['code'] == 200
        except Exception as e:
            print("异常了",e)

(6) log

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


(7) message // TODO

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


(8) report

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


(9) utils

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

# 数据库连接
import logging
import pymysql

from utils.log_util import logger
from utils.read_data import base_data

data = 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 result

    def 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().logger


if __name__ == '__main__':
    logger.info("--测试开始--")
    logger.debug("--测试结束--")

 三. 总结

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

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

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

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

相关文章

Visual Studio中调试信息格式参数:/Z7、/Zi、/ZI参数

一般的调试信息都保存在pdb文件中。 Z7参数表示这些调试信息保存到OBJ目标文件中,这样的好处是不需要单独分发PDB文件给下游。Zi就是把所有的调试信息都保存在pdb文件中,以缩小发布文件的大小。ZI和Zi类似,但是增加了热重载的能力&#xff1…

【传知代码】MonoCon解读与复现(论文复现)

前言:在快速发展的计算机视觉领域,单目视觉(Monocular Vision)技术凭借其独特的优势和广泛的应用前景,逐渐成为了研究的热点。MonoCon作为单目视觉领域的一项重要技术,其独特的算法设计和高效的性能表现&am…

使用pkg打包了一个使用了sqlite3的nodejs项目,启动后闪退

从截图来看,问题出在 sqlite3 模块上。说明在打包过程中,sqlite3 模块的 .node 文件没有正确加载。 紧急解决方法: 其实就是exe文件还需要node_modules中的sqlite3 依赖,我们直接在系统顶级放一个node_modules,且其中只…

(2024,Video2Game,NeRF,Mesh,物理模块,游戏引擎)通过单个视频实现实时、交互、逼真且兼容浏览器的环境

Video2Game: Real-time, Interactive, Realistic and Browser-Compatible Environment from a Single Video 公众号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0. 摘要 2. 相关工作 3. Video…

论文115:Reinforced GNNs for multiple instance learning (TNNLS‘24)

文章目录 1 要点2 预备知识2.1 MIL2.2 MIL-GNN2.3 Markov博弈2.4 深度Q-Learning 3 方法3.1 观测生成与交互3.2 动作选择和指导3.3 奖励计算3.4 状态转移和终止3.5 多智能体训练 1 要点 题目:用于MIL的强化GNN 代码:https://github.com/RingBDStack/RG…

Ollama 本地大模型框架

该篇教程主要讲解*Ollama的安装和简单使用* Ollama: 在本地启动并运行大型语言模型。 主要流程目录: 1.安装 2.使用 2.1.下载模型 2.2.简单使用 2.3.中文模型 2.4.中文社区 3.总结 1.安装 创建一个容器 切换”高级视图“ 参考填写 ollama oll…

ARM32开发——总线与时钟

🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 APB总线时钟树时钟树 外部晶振内部晶振 在这个例子中,这条大街和巴士构成了一套系统,我们称之为AHB总线。 …

响应式界面控件DevExtreme - 更强的数据分析和可视化功能

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NET Core,jQuery,Knockout等)构建交互式的Web应用程序。从Angular和Reac&#xff0c…

新火种AI|OpenAI要和苹果合作了?微软有些不高兴

作者:一号 编辑:美美 和苹果之间的合作,可能会称为Altman引以为傲的功绩。 根据 The Information 援引知情人士的消息,OpenAI 已经和苹果达成了协议,将在其产品中运用 OpenAI 的对话式 AI。 如果进展顺利&#xff…

gitlab服务器迁移(亲测有效)

描述:最近公司迁移gitlab,我没有迁移过,经过网上查找资料最终完成迁移,途中也遇到挺多坑和两个问题,希望能帮到你。 新服务器安装gitlab 注意:新服务器gitlab版本也需要和旧版本一致。 首先查看原Gitlab…

12V转5V5A降压芯片:AH8317的全面解析

# 12V转5V降压芯片:AH8317的全面解析 在电子设计领域,电压转换器是不可或缺的组件之一,它们允许电子设备在不同的电源电压下稳定运行。今天,我们将深入探讨一款高性能的同步降压转换器——AH8317,它以其出色的性能和广…

连锁便利店水电远程抄表管理系统是什么?

一、系统概述 连锁便利店水电远程抄表管理系统是一种高效、智能化的解决方案,旨在优化便利店的能源管理,提高运营效率。它通过先进的技术手段,实现了对便利店水电用量的实时监控和远程抄表,大大降低了人工成本,提升了…

悬剑武器库5.04版

工具介绍 悬剑5 基于“悬剑网盘”精选工具集悬剑5“飞廉”云武器库制作。 操作系统:Windows 10 专业版 锁屏密码:secquan.org 解压密码: 圈子社区secquan.org 镜像大小:33.1GB 系统占用空间63.0 GB 镜像导入 下载镜像,文末…

vm:为虚拟机配置多个虚拟网卡(ubuntu20.04)

前言: 环境:虚拟机 ubuntu 20.04 要求:如标题,但是这里针对的是 ubuntu 20.04,对于其他操作系统,可以找一下其他操作系统对应的配置文件是什么 vm 添加虚拟网卡 首先进入 vm: 点击设置&#xf…

员工恶意删除公司数据怎么办,如何防范员工恶意删除公司数据

员工恶意删除公司数据怎么办,如何防范员工恶意删除公司数据 面对员工恶意删除公司数据的情况,企业应当采取一系列紧急且有序的应对措施,以最小化损失并确保业务连续性。以下是一套推荐的应对流程: 1.立即行动: 断开网…

freertos初体验 - 在stm32上移植

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

【Python】解决Python报错:ModuleNotFoundError: No module named ‘xxx.yyy‘

🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

VNC server ubuntu20 配置

介绍 最近想使用实验室的4卡服务器跑一些深度学习实验,因为跑的是三维建图实验,需要配上可视化界面,本来自带的IPMI可以可视化,但分辨率固定在640*480,看起来很别扭,就捣鼓服务器远程可视化访问了两天&…

无法删除dll文件

碰到xxxxxx.dll文件无法删除不要慌! 通过Tasklist /m dll文件名称 去查看它和哪个系统文件绑定运行,发现是explorer.exe。 我们如果直接通过del命令【当然需要在该dll文件所在的路径中】。发现拒绝访问 我们需要在任务管理器中,将资源管理器…

【开源】在线考试系统 JAVA+Vue.js+SpringBoot 新手入门项目

目录 一、项目介绍 二、项目截图 三、核心代码 【开源】在线考试系统 JAVAVue.jsSpringBoot 新手入门项目 一、项目介绍 经典老框架SSM打造入门项目《在线考试系统》,包括班级模块、教师学生模块、试卷模块、试题模块、考试模块、考试回顾模块,项目编…