接口自动化测试-Python+Requests+Pytest+YAML+Allure配套撸码(详细)

目录:导读

    • 前言
    • 一、Python编程入门到精通
    • 二、接口自动化项目实战
    • 三、Web自动化项目实战
    • 四、App自动化项目实战
    • 五、一线大厂简历
    • 六、测试开发DevOps体系
    • 七、常用自动化测试工具
    • 八、JMeter性能测试
    • 九、总结(尾部小惊喜)


前言

接口自动化框架:Python+Requests+Pytest+YAML+Allure

通过 Python+Requests 来发送和处理HTTP协议的请求接口,使用 Pytest 作为测试执行器,使用 YAML 来管理测试数据,使用 Allure 来生成测试报告。

框架结构

api ====>> 接口封装层,如封装HTTP接口为Python接口
common ====>> 各种工具类
core ====>> requests请求方法封装、关键字返回结果类
config ====>> 配置文件
data ====>> 测试数据文件管理
operation ====>> 关键字封装层,如把多个Python接口封装为关键字
pytest.ini ====>> pytest配置文件
requirements.txt ====>> 相关依赖包文件
testcases ====>> 测试用例

请求方法封装:
在 core/rest_client.py 文件中,对 Requests 库下一些常见的请求方法进行了简单封装,以便调用起来更加方便。

class RestClient():def __init__(self, api_root_url):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, data=None, json=None, **kwargs):return self.request(url, "POST", data, json, **kwargs)def put(self, url, data=None, **kwargs):return self.request(url, "PUT", data, **kwargs)def delete(self, url, **kwargs):return self.request(url, "DELETE", **kwargs)def patch(self, url, data=None, **kwargs):return self.request(url, "PATCH", data, **kwargs)def request(self, url, method, data=None, json=None, **kwargs):url = self.api_root_url + urlheaders = dict(**kwargs).get("headers")params = dict(**kwargs).get("params")files = dict(**kwargs).get("params")cookies = dict(**kwargs).get("params")self.request_log(url, method, data, json, params, headers, files, cookies)if method == "GET":return self.session.get(url, **kwargs)if method == "POST":return requests.post(url, data, json, **kwargs)if method == "PUT":if json:# PUT 和 PATCH 中没有提供直接使用json参数的方法,因此需要用data来传入data = complexjson.dumps(json)return self.session.put(url, data, **kwargs)if method == "DELETE":return self.session.delete(url, **kwargs)if method == "PATCH":if json:data = complexjson.dumps(json)return self.session.patch(url, data, **kwargs)

HTTP接口 封装为 Python接口:
在 api/user.py 文件中,将上面封装好的HTTP接口,再次封装为不同的Python接口。不同的Python接口,会处理不同URL下的请求。

class User(RestClient):def __init__(self, api_root_url, **kwargs):super(User, self).__init__(api_root_url, **kwargs)def list_all_users(self, **kwargs):return self.get("/users", **kwargs)def list_one_user(self, username, **kwargs):return self.get("/users/{}".format(username), **kwargs)def register(self, **kwargs):return self.post("/register", **kwargs)def login(self, **kwargs):return self.post("/login", **kwargs)def update(self, user_id, **kwargs):return self.put("/update/user/{}".format(user_id), **kwargs)def delete(self, name, **kwargs):return self.post("/delete/user/{}".format(name), **kwargs)

关键字返回结果类:
在 core/result_base.py 下,定义了一个空类 ResultBase ,该类主要用于自定义关键字返回结果。

class ResultBase():pass"""
自定义示例:
result = ResultBase()
result.success = False
result.msg = res.json()["msg"]
result.response = res
"""` 

在多流程的业务场景测试下,通过自定义期望保存的返回数据值,以便更好的进行断言。

关键字封装:
关键字应该是具有一定业务意义的,在封装关键字的时候,可以通过调用多个Python接口来完成。

在某些情况下,比如测试一个充值接口的时候,在充值后可能需要调用查询接口得到最新账户余额,来判断查询结果与预期结果是否一致,那么可以这样来进行测试:

1、首先,可以把 充值-查询 的操作封装为一个关键字,在这个关键字中依次调用充值和查询的接口,并可以自定义关键字的返回结果。

2、接着,在编写测试用例的时候,直接调用关键字来进行测试,这时就可以拿到关键字返回的结果,那么断言的时候,就可以直接对关键字返回结果进行断言。

测试用例层

1、根据用例名分配测试数据
测试数据位于 data 文件夹下,在这里使用 YAML 来管理测试数据,同时要求测试数据中第一层的名称,需要与测试用例的方法名保持一致,如 test_get_all_user_info 、test_delete_user。

test_get_all_user_info:# 期望结果,期望返回码,期望返回信息# except_result, except_code, except_msg- [True, 0, "查询成功"]
省略
test_delete_user:# 删除的用户名,期望结果,期望返回码,期望返回信息# username, except_result, except_code, except_msg- ["测试test", True, 0, "删除用户信息成功"]- ["wintest3", False, 3006, "该用户不允许删除"]

这里借助 fixture 方法,我们就能够通过 request.function.name 自动获取到当前执行用例的函数名 testcase_name ,当我们传入测试数据 api_data 之后,接着便可以使用 api_data.get(testcase_name) 来获取到对应用例的测试数据。

import pytest
from testcases.conftest import api_data@pytest.fixture(scope="function")
def testcase_data(request):testcase_name = request.function.__name__return api_data.get(testcase_name)`

2、数据准备和清理
在接口自动化中,为了保证用例可稳定、重复地执行,我们还需要有测试前置操作和后置操作,即数据准备和数据清理工作。

@pytest.fixture(scope="function")
def delete_register_user():"""注册用户前,先删除数据,用例执行之后,再次删除以清理数据"""del_sql = base_data["init_sql"]["delete_register_user"]db.execute_db(del_sql)logger.info("注册用户操作:清理用户--准备注册新用户")logger.info("执行前置SQL:{}".format(del_sql))yield # 用于唤醒 teardown 操作db.execute_db(del_sql)logger.info("注册用户操作:删除注册的用户")logger.info("执行后置SQL:{}".format(del_sql))

在这里,以用户注册用例为例。对于前置操作,我们应该准备一条删除SQL,用于将数据库中已存在的相同用户删除,对于后置操作,我们应该再执行删除SQL,确保该测试数据正常完成清理工作。

在测试用例中,我们只需要在用例上传入 fixture 的函数参数名 delete_register_user ,这样就可以调用 fixture 实现测试前置及后置操作。当然,也可以使用pytest装饰器 @pytest.mark.usefixtures() 来完成,如:

@pytest.mark.usefixtures("delete_register_user")` 

3、Allure用例描述
在这里,我们结合 Allure 来实现输出测试报告,同时我们可以使用其装饰器来添加一些用例描述并显示到测试报告中,以便报告内容更加清晰、直观、可读。

如使用 @allure.title() 自定义报告中显示的用例标题,使用 @allure.description() 自定义用例的描述内容,使用 @allure.step() 可在报告中显示操作步骤,使用 @allure.issue() 可在报告中显示缺陷及其链接等。

@allure.step("步骤1 ==>> 注册用户")
def step_1(username, password, telephone, sex, address):logger.info("步骤1 ==>> 注册用户 ==>> {}, {}, {}, {}, {}".format(username, password, telephone, sex, address))@allure.severity(allure.severity_level.NORMAL)
@allure.epic("针对单个接口的测试")
@allure.feature("用户注册模块")
class TestUserRegister():"""用户注册"""@allure.story("用例--注册用户信息")@allure.description("该用例是针对获取用户注册接口的测试")@allure.issue("https://www.cnblogs.com/wintest", name="点击,跳转到对应BUG的链接地址")@allure.testcase("https://www.cnblogs.com/wintest", name="点击,跳转到对应用例的链接地址")@allure.title("测试数据:【 {username},{password},{telephone},{sex},{address},{except_result},{except_code},{except_msg}】")@pytest.mark.single@pytest.mark.parametrize("username, password, telephone, sex, address, except_result, except_code, except_msg",api_data["test_register_user"])@pytest.mark.usefixtures("delete_register_user")def test_delete_user(self, login_fixture, username, except_result, except_code, except_msg):

测试报告效果展示

在命令行执行命令:pytest 运行用例后,会得到一个测试报告的原始文件,但这个时候还不能打开成HTML的报告,还需要在项目根目录下,执行命令启动 allure 服务:

# 需要提前配置allure环境,才可以直接使用命令行
allure serve ./report`
下面是我整理的2023年最全的软件测试工程师学习知识架构体系图

一、Python编程入门到精通

请添加图片描述

二、接口自动化项目实战

请添加图片描述

三、Web自动化项目实战

请添加图片描述

四、App自动化项目实战

请添加图片描述

五、一线大厂简历

请添加图片描述

六、测试开发DevOps体系

请添加图片描述

七、常用自动化测试工具

请添加图片描述

八、JMeter性能测试

请添加图片描述

九、总结(尾部小惊喜)

在追逐梦想的路上,不要畏惧困难与挫折,坚持不懈地奋斗,只有拼搏,才能超越自我,创造属于自己的辉煌。相信自己的能力,勇往直前,每一次努力都是一次进步,每一次奋斗都是一次成长。

不论前路多么艰难,只要你心怀梦想,勇往直前,坚持不懈地奋斗,就能超越自我,创造属于自己的辉煌。相信自己的能力,勇敢追求,每一次努力都是一次进步,每一次奋斗都是一次蜕变。

每个人都有属于自己的光芒,只要努力奋斗,勇敢面对困难,坚持追求,就能绽放璀璨,实现梦想,让生命在奋斗中闪耀出绚丽的色彩。

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

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

相关文章

[Java] 观察者模式简述

模式定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,他的所有依赖者都会收到通知并且更新 依照这个图,简单的写一个代码 package Section1.listener;import java.ut…

前端程序员入门:先学Vue3还是Vue2?

一、前言 对于新手来说,学习Vue.js框架时往往会有这样一个疑问:应该先学习Vue2还是直接学习Vue3?在回答这个问题之前,我们先简单介绍一下Vue.js框架。 Vue.js是一个轻量级的MVVM(Model-View-ViewModel)框架,它以数据驱…

el-table表格自动滚动

实现效果如下: 功能点: 1. 当表格内容超出时,自动滚动,滚动到最后一条之后在从头滚动。 2. 表格中的数据会定时刷新,刷新后数据更新。 3. 鼠标移入表格中,停止滚动;移出后,继续滚…

nginx几种常见的负载均衡策略

在服务器集群中,Nginx起到一个代理服务器的角色(即反向代理),为了避免单独一个服务器压力过大,将来自用户的请求转发给不同的服务器。 根据权重负载均衡 指定轮询几率,weight和访问比率成正比&#xff0c…

算法训练营第四十九天||● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II

● 121. 买卖股票的最佳时机 暴力和贪心都可以解决 主要讲解动态规划 dp数组:我们把dp数组定义为一个二维的vector容器 dp[i][0]表示第i天持有股票手中的金额:它可以是当天买入的也可以是之前买入的 dp[i][1]表示第i天不持有股票手中的金额&#xf…

VXLAN集中式网关部署(静态方式)

目录 1. 网络拓扑1.1 配置思路1.2 数据准备2. 配置Underlay网络2.1 配置CE12.2 配置CE22.3 配置CE32.4 查看OSPF结果2.5 配置LSW12.6 配置LSW23. 配置Overlay网络二层互通(同网段)3.1 配置CE13.2 配置CE23.3 配置CE33.4 Server13.5 Server23.6 Server33.7 Server43.8 抓包分析…

Kafka入门到起飞系列 - 副本机制,什么是副本因子呢?

我们一直在讲一个主题会有多个分区,这多个分区可以分布在一台服务器上,也可以分布在多台服务器上,还可以增加分区(Kafka目前只支持分区),这是Kafka提供的一种横向扩展的手段 比如我们创建了一个主题&#x…

YAML+PyYAML笔记 2 | YAML缩进、分离、注释简单使用

2 | YAML缩进、分离、注释简单使用 1 简介2 缩进3 分离4 多行文本4.1 折叠块4.2 字面块4.3 引用块 5 注释5.1 行内注释5.2 块注释5.3 完美注释示例 1 简介 YAML 不是一种标记语言,而是一种数据格式;使用缩进和分离来表示数据结构,不需要使用…

与 ChatGPT 进行有效交互的几种策略

在这篇文章中,您将了解即时工程。尤其, 如何在提示中提供对响应影响最大的信息什么是角色、正面和负面提示、零样本提示等如何迭代使用提示来利用 ChatGPT 的对话性质 废话不多说直接开始吧!!! 提示原则 快速工程是有…

Safari 查看 http 请求

文章目录 1、开启 Safari 开发菜单2、显示 JavaScript 控制台 1、开启 Safari 开发菜单 Safari 设置中,打开开发菜单选项 *** 选择完成后,Safari 的目录栏就会出现一个 开发 功能。 2、显示 JavaScript 控制台 开启页面后,在开发中选中 显…

【Linux后端服务器开发】数据链路层

目录 一、以太网 二、MAC地址 三、MTU 四、ARP协议 一、以太网 “以太网”不是一种具体的网路,而是一种技术标准:既包含了数据链路层的内容,也包含了一些物理层的内容,例如:规定了网络拓扑结构、访问控制方式、传…

@Bean的作用

Bean通常和Configuration注解一起使用 Bean可以用在方法上,方法返回的对象交给spring容器管理,和提供给其他程序组件使用 Bean是一个注解,用于将方法标记为Spring容器中的一个Bean。具体来说,Bean注解可以用于方法上&#xff0c…

Android 在程序运行时申请权限——以自动拨打电话为例

Android 6.0及以上系统在使用危险权限时必须进行运行时权限处理。 main_activity.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://sche…

Git 绑定账号 和clone

一:环境: 下载安装完成Git,在桌面或文件夹下(在你将要保存代码的位置)右击可以看到Git Bash Here,点击可以进入黑窗口 二:配置公钥 1.查看当前状态(如果已绑定,且知道密码可以登陆,可以直接获取SSH公钥并配置即可拉取代码) git config --list 2.配置全局git用户名和邮箱 …

使用Python搭建代理服务器- 爬虫代理服务器详细指南

搭建一个Python爬虫代理服务器可以让你更方便地管理和使用代理IP。下面是一个详细的教程来帮助你搭建一个简单的Python爬虫代理服务器&#xff1a; 1. 首先&#xff0c;确保你已经安装了Python。你可以在官方网站(https://www.python.org/)下载并安装最新版本的Python。 2. 安…

c#中的Math.Ceiling和Math.floor()和Math.Round()

Math.Ceiling(),只要有小数就加1(小数部分不为0&#xff09; 例如&#xff1a; Math.Ceiling(0.0) -> 0 Math.Ceiling(0.1) -> 1 Math.Ceiling(0.2) -> 1 Math.Ceiling(0.3) -> 1 Math.Ceiling(0.4) -> 1 Math.Ceiling(0.5) -> 1 Math.Ceiling(0.6) -> 1…

WPF中Binding使用StringFormat格式化字符串方法

货币格式 <TextBlock Text"{Binding Price, StringFormat{}{0:C}}" /> // $123.46货币格式&#xff0c;一位小数 <TextBox Text"{Binding Price, StringFormat{}{0:C1}}" /> // $123.5前文字 <TextBox Text"{Binding Price, String…

本地Git仓库和GitHub仓库SSH传输

SSH创建命令解释 ssh-keygen 用于创建密钥的程序 -m PEM 将密钥的格式设为 PEM -t rsa 要创建的密钥类型&#xff0c;本例中为 RSA 格式 -b 4096 密钥的位数&#xff0c;本例中为 4096 -C “azureusermyserver” 追加到公钥文件末尾以便于识别的注释。 通常以电子邮件地址…

序列化模块pickle和json有什么区别

目录 什么是序列化模块pickle 什么是序列化模块json pickle和json有什么区别 总结 什么是序列化模块pickle pickle是Python中的内置模块&#xff0c;用于将Python对象序列化和反序列化为字节流。它提供了一种将复杂的数据结构&#xff08;如列表、字典、类实例等&#xff0…

练习时长两年半的入侵检测

计算机安全的三大中心目标是&#xff1a;保密性 (Conf idential ity) 、完整性 (Integrity) 、可用性 (Availability) 。 身份认证与识别、访问控制机制、加密技术、防火墙技术等技术共同特征就是集中在系统的自身加固和防护上&#xff0c;属于静态的安全防御技术&#xff0c;…