快速上手pytest
1. pytest的基础
1.1 什么是pytest
pytest 是 python 中的一个测试框架,用于编写简洁、可扩展的测试代码,帮助开发者验证结果是否与预期相符。
python 中有很多的测试框架,那我们为什么要学习 pytest 呢?
pytest 的优势:
- 不需要复杂的类继承(不像 unittest)
- 支持断言直接使用 python 的 assert 语句
- 提供丰富的插件生态(如生成 HTML 报告、并行测试等)
1.2 pytest的安装
pytest 属于 python 的第三方库(不属于标准库),所有在使用之前需要在 terminal 中进行安装
pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple
后面指定的是国内源下载,能够提高下载的速度
1.3 第一个测试例子
创建一个文件:test_first.py
python文件内容为:
def add(num1, num2):return num1 + num2def test_add():assert add(1, 2) == 3
运行代码:pytest test_first.py
2. pytest的核心功能
2.1 测试发现规则
pytest 会自动发现以下的文件:
- 文件名以 test_ 开头 或 _test结尾(如 test_first.py 或 first_test.py)
- 类名以 Test 开头
- 函数名以 test_开头
文件名符合规则,是 pytest 处理文件的前提条件。类/函数符合规则,是执行具体测试的必要条件。
若文件名符合规则,类符合规则,类中的函数不符合规则,则会跳过类中的不符合规则的函数。除非在符合规则的函数里面调用不符合规则的函数。
符合规则的文件+类+不符合规则的函数 :
class TestAdd:def add(self):print(1 + 1)
运行结果:
符合规则的文件+类+函数:
class TestAdd:def test_add(self):print(1 + 1)
运行结果:
2.2 运行测试的常用方式
运行所有的测试:pytest
运行指定文件:pytest 文件名(符合规则)
运行指定目录:pytest 目录/
运行包含关键字的测试:pytest -k "add" #运行名称关于add的测试
遇到错误时停止:pytest --pdb #进入调试模式
2.3 断言(assert)
直接使用 python 的 assert 语句。
断言的作用:判断实际结果是否与预期结果一致。
在 pytest 中运行测试时,控制台会通过特定符号直观反馈每个测试用例的执行结果。
以下是常见的符号及其含义:
符号 | 含义 | 触发场景 |
. | 测试通过 | 断言成功且无异常 |
F | 测试失败 | 断言失败(如 assert 1 == 2) |
E | 代码错误 | 测试代码本身抛出异常(非断言失败) |
s | 测试跳过 | 使用 @pytest.mark.skip 主动跳过测试 |
x | 预期失败(XFAIL) | 测试标记为预期失败且确实失败 |
X | 意外通过(XPASS) | 测试标记为预期失败但实际通过了 |
w | 警告 | 代码触发了警告(如弃用函数) |
2.4 夹具(Fixture)
2.4.1 夹具的作用与使用
夹具的作用:为测试用例提供预置的环境和资源,避免重复写相同的准备代码,让测试更简洁、可维护。
- 数据库连接
- 临时文件
- 模拟对象
- 共享配置
举个例子:假设你要测试“煮不同口味的面条”
没有夹具:每次煮面都要自己拆包装、烧水、煮面、吃完洗碗......重复劳动。
有夹具:小助手自动帮你完成这些事:提前烧好一锅水(前置准备)、煮好面递给你(提供资源)、你吃完后,它自动洗碗(清理垃圾)。你只需要专注测试“面的味道”,其他杂活都交给它。
夹具的定义:用@pytest.fixture装饰器定义一个夹具
写一个简单的代码(可能与实际业务不符),方便大家理解:
@pytest.fixture
def user():return "Alice"
夹具的使用:在测试函数中将夹具作为参数传入即可使用
def test_user(user):print(user)
运行结果:
2.4.2 夹具的作用范围(scope)
通过 scope 参数控制夹具的作用域:
- function(默认):每个测试函数执行一次
- class:每个测试类执行一次
- module:每个 python 文件执行一次
- session:整个 pytest 运行过程执行一次
大家看到上面的夹具作用域,可能就有点懵了。可能不明白什么叫做执行一次,接下来就给大家深入解析一下:
并不是说它们只能执行一次,而是说当设置不同的scope参数内容时,它们的作用域是不同的。
作用域为function的代码理解:
import pytestclass TestFruit:@pytest.fixture(scope="function")def ret_fruit(self):return {"A": "apple","P": "pear","W": "watermelon"}def test_fruit1(self, ret_fruit):ret_fruit["A"] = "avocado"print(ret_fruit)def test_fruit2(self, ret_fruit):print(ret_fruit)
运行结果:
分析:
夹具作用域(scope="function"):
- 规则:夹具 ret_fruit 在 每个测试函数执行前初始化一次,每个测试函数获得独立的字典对象。
- 初始化:每个测试函数(如:test_fruit1、test_fruit2)执行前,都会调用一次 ret_fruit,生成新字典。
- 清理:每个测试函数结束后清理资源。
- 隔离性:每个测试函数操作的字典是完全独立的对象,互不干扰。
字典虽然是可变的,但 ret_fruit 夹具 每次返回一个新字典。所以在 test_fruit1 中修改字典,不会影响 test_fruit2,因为它们操作的是不同的对象。
作用域为 class 的代码理解:
import pytestclass TestFruit:@pytest.fixture(scope="class")def ret_fruit(self):return {"A": "apple","P": "pear","W": "watermelon"}def test_fruit1(self, ret_fruit):ret_fruit["A"] = "avocado"print(ret_fruit)def test_fruit2(self, ret_fruit):print(ret_fruit)
运行结果:
分析:
夹具的作用域(scope="class"):
- 规则:夹具 ret_fruit 在测试类的 第一个测试方法执行前初始化一次,后续所有测试方法共享同一个对象。
- 初始化:在 TestFruit 类的第一个测试方法(如 test_fruit1)执行前生成字典。
- 清理:在 TestFruit 类的最后一个测试方法执行后清理。
- 共享性:类内的所有测试方法(如 test_fruit1 和 test_fruit2)共享同一个字典对象。
字典是可变对象,在 test_fruit1 中修改 ret_fruit["A"] = "avocado" 会直接影响 test_fruit2 中接收的 ret_fruit,因为 ret_fruit 是同一个字典的引用。
2.5 pytest的参数化
2.5.1 什么是参数化测试?
参数化测试:就是用不同测试数据,去反复运行同一个测试函数,避免重复写类似的测试代码。
举例说明:学过测试的小伙伴应该知道,当我们去测一个登录功能的时候,是会有很多条测试用例去测这个登录功能的。那我们进行登录自动化接口测试的时候,那么登录功能就会被抽象成一个函数,测这个功能的测试数据又有很多。如果每个情况都写一个测试函数,那么代码就会很冗余。参数化就可以让你用一个函数跑遍所有情况。
2.5.2 参数化的使用
参数化的使用:@pytest.mark.parametrize("参数名", 参数值列表)
import pytestdef add(a, b):return a + b# 装饰器写法:@pytest.mark.parametrize("参数名", 参数值列表)
@pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (2, 3, 5)])
def test_add(a, b, expected):assert add(a, b) == expected
运行结果:
@pytest.mark.parametrize:这是 pytest 提供的参数化装饰器。
第一个参数:“参数名” 是字符串,多个参数用逗号隔开(如 "a, b, expected")。
第二个参数:是一个列表,列表中的每个元素是一组参数值(如 (1, 2, 3)对应一次测试)。
测试函数参数:参数名必须和装饰器中的参数名一一对应(如 a, b, expected)。
上述代码执行测试时,pytest会自动生成 2 个测试用例:
- 用 a = 1, b = 2, expected = 3 运行一次 test_add。
- 用 a = 2, b = 3, expected = 5 运行一次 test_add。
注意:实际中参数值列表部分,通常会采用调用其他函数(获取文件数据函数)获取对应的返回值,来获取参数值列表部分。这样就能够实现代码与数据的分离。
3. pytest的高级功能
3.1 标记(Mark)
3.1.1 跳过测试
跳过测试:@pytest.mark.skip 和 @pytest.mark.skipif
作用:在某些条件下跳过测试,避免执行不必要或暂时无法运行的测试。
直接跳过:
import pytest@pytest.mark.skip(reason="该功能尚未实现")
def test_feature_not_implemented():assert False # 不会执行
运行结果:
动态条件跳过:
import pytest@pytest.mark.skipif(1 == 1, reason="条件成立跳过")
def test_condition_skipping():pass
运行结果:
这个只有条件成立才会跳过,不成立则不会跳过。
3.1.2 预期失败
预期失败:@pytest.mark.xfail
作用:标记已知会失败的测试,测试失败时不计入错误统计(显示为 xfailed)
import pytest@pytest.mark.xfail
def test_beta_feature():assert False
运行结果:
3.2 异常测试
作用:验证代码是否抛出预期的异常类型和错误信息
基础异常断言:pytest.raises
import pytestdef test_divide_by_zero():with pytest.raises(ZeroDivisionError):10 / 0
结果抛出 ZeroDivisionError,才能测试通过。
运行结果:
装饰器方式:@pytest.mark.xfail(raises=...)
适用于整个测试函数都预期抛出异常的场景:
import pytest@pytest.mark.xfail(raises=IndexError)
def test_out_of_bounds():my_list = [1, 2, 3]return my_list[100] # 预期会抛出IndexError
运行结果:
相关文章:

快速上手pytest
1. pytest的基础 1.1 什么是pytest pytest 是 python 中的一个测试框架,用于编写简洁、可扩展的测试代码,帮助开发者验证结果是否与预期相符。 python 中有很多的测试框架,那我们为什么要学习 pytest 呢? pytest 的优势&…...

设备驱动与文件系统:02 键盘
操作系统中键盘驱动的讲解 在这一讲中,我将为大家讲解键盘相关内容。从上一讲开始,我们进入了操作系统第四个部分的学习,也就是操作系统对设备的驱动与管理。 上一讲我们探讨的是显示器,并且提到,一个终端设备是由显示…...
matlab分布式电源接入对配电网的影响
MATLAB仿真的分布式电源接入对于配电网的影响,潮流计算加了固定的pq 分布式电源接入对配电网的影响/bustypes.m , 1004 分布式电源接入对配电网的影响/case34.m , 5385 分布式电源接入对配电网的影响/case9.m , 1366 分布式电源接入对配电网的影响/dSbus_dV.m , 14…...
前端ul-image的src接收base64快捷写法
前端ul-image的src接收base64快捷写法 data:image/png;base64,你的base64数据 注意如果是jpg就改成jpg,中间的逗号格式要注意,/注意不要反了 假设后端返回的detail中的url已经是base64格式,下面是示例 <u-image height"120rpx"…...

交通违法拍照数据集,可识别接打电话,不系安全带的行为,支持YOLO,COCO JSON,VOC XML格式的标注数据集 最高正确识别率可达88.6%
交通违法拍照数据集 数据集概述 数据来源:交通监控摄像头、执法记录仪、公开数据集数据类型:图像、视频、元数据(时间、地点、车辆信息)违法类型标注:接打电话、未系安全带 数据采集与标注方法 采集设备࿱…...

Qt OpenGL 3D 编程入门
Qt 提供了强大的 OpenGL 集成功能,使得在 Qt 应用中实现 3D 图形变得更加简单。以下是使用 Qt 进行 OpenGL 3D 编程的基础知识。 1. 环境配置 创建 Qt 项目 新建 Qt Widgets Application 项目 在 .pro 文件中添加 OpenGL 模块: qmake QT co…...

性能优化 - 工具篇:基准测试 JMH
文章目录 Pre引言1. JMH 简介2. JMH 执行流程详解3. 关键注解详解3.1 Warmup3.2 Measurement3.3 BenchmarkMode3.4 OutputTimeUnit3.5 Fork3.6 Threads3.7 Group 与 GroupThreads3.8 State3.9 Setup 与 TearDown3.10 Param3.11 CompilerControl 4. 示例代码与分析4.1 关键点解读…...
Ubuntu 中安装 PostgreSQL 及常规操作指南
目录 一、安装 PostgreSQL 最新版本安装(推荐) 安装特定版本(如 14) 二、基本服务管理 三、连接数据库 四、常规数据库操作 1. 用户与权限管理 2. 数据库管理 3. 表操作 4. 数据操作 五、常用 psql 元命令 六、备份与恢…...

Nginx网站服务:从入门到LNMP架构实战
🏡作者主页:点击! Nginx-从零开始的服务器之旅专栏:点击! 🐧Linux高级管理防护和群集专栏:点击! ⏰️创作时间:2025年5月30日14点22分 前言 说起Web服务器,…...

Java面试八股--08-数据结构和算法篇
1、怎么理解时间复杂度和空间复杂度 时间复杂度和空间复杂度一般是针对算法而言,是衡量一个算法是否高效的重要标准。先纠正一个误区,时间复杂度并不是算法执行的时间,在纠正一个误区,算法不单单指冒泡排序之类的,一个…...

Java面试八股--06-Linux篇
目录 一、Git 1、工作中git开发使用流程(命令版本描述) 2.Reset与Rebase,Pull与Fetch的区别 3、git merge和git rebase的区别 4、git如何解决代码冲突 5、项目开发时git分支情况 二、Linux 1、Linux常用的命令 2、如何查看测试项目的…...
Ajax技术分析方法全解:从基础到企业级实践(2025最新版)
引言 Ajax技术自2005年正式命名以来,已支撑全球83%的Web应用实现异步交互。2025年最新数据显示,单页面应用(SPA)的Ajax请求密度已达日均120亿次/应用。本文将系统化解析Ajax分析方法论,涵盖从基础原理到企业级工程实践的完整技术栈。 一、Ajax技术架构解构 1.1 核心组件…...
Unity 性能优化终极指南 — GameObject 篇
🎯 Unity 性能优化终极指南 — GameObject 方法篇 🧩 GameObject 是什么?—— Unity世界的核心实体 GameObject 是 Unity 引擎中最核心、最基础的构建单元。它代表了场景中的一个实体对象,可以是一个角色、一个UI元素、一盏灯光、…...

dvwa7——SQL Injection
LOW: f12打开hackbar 一:判断注入类型 输入id1报错 闭合单引号 ,页面恢复正常 所以为单引号字符型 二:开始攻击 1.判断列数 ?id1 order by 2-- 到3的时候开始报错,所以一共两列 2.爆回显位置 ?id-1 union s…...
Spring AI 项目实战(四):Spring AI + DeepSeek 超参数优化——智能化机器学习平台(附完整源码)
系列文章 序号文章名称1Spring AI 项目实战(一):Spring AI 核心模块入门2Spring AI 项目实战(二):Spring AI + DeepSeek 深度实战(附完整源码)3Spring AI 项目实战(三):Spring AI + DeepSeek 打造智能客服系统(附完整源码)4Spring AI 项目实战(四):Spring AI +…...
Axure疑难杂症:中继器图片替换功能优化(支持修改已有记录-玩转中继器)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 案例视频: 中继器图片替换功能优化 课程主题:中继器图片替换功能优化(支持修改已有记录) 主要内…...

sqlite3 命令行工具详细介绍
一、启动与退出 启动数据库连接 sqlite3 [database_file] # 打开/创建数据库文件(如 test.db) sqlite3 # 启动临时内存数据库 (:memory:) sqlite3 :memory: # 显式启动内存数据库文件不存在时自动创建不指定文件名则使用临时内…...

ubuntu 22.04 编译安装nignx 报错 openssl 问题
前言 Ubuntu 20.04 中安装 Nginx (通过传包编译的方式)、开启关闭防火墙、开放端口号 在ubuntu 22.04.3 服务器上照着上面的文章 通过传包编译的方式安装nginx-1.18.0 的时候报错,报错内容如下: src/event/ngx_event_openssl.c: In function ‘ngx_ssl…...

线程相关面试题
提示:线程相关面试题,持续更新中 文章目录 一、Java线程池1、Java线程池有哪些核心参数,分别有什么的作用?2、线程池有哪些拒绝策略?3、说一说线程池的执行流程?4、线程池核心线程数怎么设置呢?4、Java线程…...

pikachu通关教程-目录遍历漏洞(../../)
目录遍历漏洞也可以叫做信息泄露漏洞、非授权文件包含漏洞等. 原理:目录遍历漏洞的原理比较简单,就是程序在实现上没有充分过滤用户输入的../之类的目录跳转符,导致恶意用户可以通过提交目录跳转来遍历服务器上的任意文件。 这里的目录跳转符可以是../…...

Maven-生命周期
目录 1.项目对象模型 2.依赖管理模型 3.仓库:用于存储资源,管理各种jar包 4.本地仓库路径 1.项目对象模型 2.依赖管理模型 3.仓库:用于存储资源,管理各种jar包 4.本地仓库路径...
Hadoop复习(九)
Azkaban工作流管理器 选择 问题 1 判断题 2 / 2 分 工作流是指具有依赖的一组job任务,被依赖的job任务最后执行 正确 错误 问题 2 判断题 2 / 2 分 Azkaban兼容任何版本的Hadoop 正确 错误 问题 3 判断题 2 / 2 分 独立服务器模式下,Azkab…...

Matlab实现LSTM-SVM回归预测,作者:机器学习之心
Matlab实现LSTM-SVM回归预测,作者:机器学习之心 目录 Matlab实现LSTM-SVM回归预测,作者:机器学习之心效果一览基本介绍程序设计参考资料 效果一览 基本介绍 代码主要功能 该代码实现了一个LSTM-SVM回归预测模型,核心流…...

Spring Boot 自动配置原理:从入门到精通
Spring Boot 的自动配置是其核心特性之一,它极大地简化了 Spring 应用的开发,让开发者可以专注于业务逻辑,而无需编写大量的配置代码。 本文将深入探讨 Spring Boot 自动配置的原理,帮助你理解其工作机制,并能灵活运用…...
实践深度学习:构建一个简单的图像分类器
引言 深度学习在图像识别领域取得了巨大的成功。本文将指导你如何使用深度学习框架来构建一个简单的图像分类器,我们将以Python和TensorFlow为例,展示从数据准备到模型训练的完整流程。 环境准备 在开始之前,请确保你的环境中安装了以下工…...

腾讯 ovCompose 开源,Kuikly 鸿蒙和 Compose DSL 开源,腾讯的“双”鸿蒙方案发布
近日,腾讯的 ovCompose 和 Kuikly 都发布了全新开源更新,其中 Kuikly 在之前我们聊过,本次 Kuikly 主要是正式开源鸿蒙支持部分和 Compose DSL 的相关支持,而 ovCompose 是腾讯视频团队基于 Compose Multiplatform 生态推出的跨平…...

PYTHON调用讯飞C/C++动态库实现离线语音合成并且实时播放
语音合成(Text-to-Speech, TTS)技术在现代应用中扮演着越来越重要的角色,从智能客服到有声读物,从导航系统到辅助工具,TTS技术无处不在。本文将详细介绍如何使用Python结合科大讯飞的离线SDK实现一个本地化的语音合成系统。 技术背景 离线语…...

黑马Java面试笔记之 消息中间件篇(RabbitMQ)
一. 消息丢失问题 RabbitMQ如何保证消息不丢失? 使用场景有: 异步发送(验证码、短信、邮件... )MYSQL和Redis,ES之间的数据同步分布式事务削峰填谷...... 消息丢失原因会有三种情况,分别分析一下 1.1 生…...
Vue中安装插件的方式
一. 认识Vue插件 1.1. 通常向Vue全局添加一些功能时,会采用插件的模式,它有两种编写方式: 1.1.1. 对象类型:一个对象,但是必须包含一个install的函数,该函数会在安装插件时执行 // 方式一:传入…...
如何提高工作效率
最近,跟一个同事同时测同一业务,在对比自己与同事的产出过程中,发现,别人工作效率极高,产出也比较大。最重要的是,别人每天晚上走得早,自己就算加班到九点十点,似乎产出都没别人高。…...