Pytest学习教程_基础知识(一)

news2024/11/16 9:42:04

前言

pytest是一个用于编写和执行Python单元测试的框架。它提供了丰富的功能和灵活性,使得编写和运行测试变得简单而高效。

  pytest的一些主要特点和解释如下:

  • 自动发现测试:pytest会自动查找以"test_"开头的文件、类和函数,并将其识别为测试用例。这样可以避免手动编写复杂的测试套件。
  • 参数化测试:pytest支持使用@pytest.mark.parametrize装饰器来定义参数化测试。通过将不同的参数传递给测试函数,可以轻松地执行多次测试并检查不同输入组合的结果。
  • 断言支持:pytest提供了丰富而灵活的断言库,用于验证预期结果与实际结果是否一致。这些断言函数可以处理各种数据类型和比较逻辑,使编写断言语句变得更简单和直观。
  • 夹具(Fixture):夹具是pytest的一个强大特性,用于在测试之前准备环境并在测试之后进行清理工作。夹具可以帮助您创建和管理共享的测试资源,例如数据库连接、临时文件等。
  • 插件系统:pytest具有可扩展的插件系统,可以根据需要添加各种插件来扩展其功能。这些插件可以用于生成测试报告、集成其他测试工具、修改测试执行流程等。

总结来说,pytest是一个功能强大且易于使用的Python单元测试框架,它提供了丰富的特性和灵活的配置选项,使开发人员能够高效地进行测试驱动的开发,并保证代码质量和可靠性。

一、安装

1、pytest 安装

安装命令: pip install -U pytest
查看版本: pytest --version

2、pytest 扩展插件

pip install pytest-cov
pip install pytest-html
pip install pytest-xdist
pip install pytest-repeat
pip install pytest-mock
pip install pytest-selenium
pip install pytest-timeout
pip install pytest-django
pip install pytest-flask
pip install pytest-bdd
pip install pytest-datadir
pip install pytest-ordering
pip install pytest-rerunfailures
pip install pytest-base-url
pip install allure-pytest
pip install pytest-randomly
pip install pytest-asyncio
  • pytest-cov: 生成测试覆盖报告,显示代码中被测试覆盖的部分
  • pytest-html: 生成漂亮的 HTML 报告,以可视化形式展示测试结果
  • pytest-xdist: 在多个进程或主机上并行执行测试,提高测试速度
  • pytest-repeat: 重复运行测试用例,用于检测稳定性和偶发性错误
  • pytest-mock: 使用 Mock 对象轻松地进行模拟和断言
  • pytest-selenium: 在 Selenium 中运行测试,用于自动化 Web 应用程序的端到端测试
  • pytest-timeout: 设置测试运行的超时时间,避免由于长时间运行而导致的阻塞
  • pytest-django: 对 Django 项目的测试提供支持和增强功能
  • pytest-flask: 对 Flask 应用程序的测试提供支持和增强功能
  • pytest-bdd: 使用行为驱动开发(BDD)方法编写测试,结合 Gherkin 语法
  • pytest-datadir: 在测试运行时访问测试数据目录
  • pytest-ordering: 控制测试函数的执行顺序
  • pytest-rerunfailures: 重新运行失败的测试用例,用于处理偶发性失败
  • pytest-base-url: 设置基本的 URL,用于在 Web 应用程序的测试中引用
  • allure-pytest: 生成 Allure 报告,提供详细和交互式的测试结果
  • pytest-randomly: 随机化测试用例的执行顺序,帮助发现不确定性问题
  • pytest-asyncio: 支持异步测试,用于编写基于 asyncio 的异步代码的测试

二、用例设计原则

  • 文件名要求: 通常 pytest 会自动发现以 test_ 开头或 _test 结尾的文件作为测试文件,但也可以通过配置进行自定义。例如 test_example.py 或 example_test.py 都符合命名约定。

  • 以 test_ 开头的函数: pytest 将识别以 test_ 开头的函数作为测试用例,这些函数应该包含您要测试的特定行为或功能。例如 def test_addition(): 是一个以 test_ 开头的测试用例函数。

  • 以 Test 开头的类和以 test_ 开头的方法: pytest 另一个常见的约定是,以 Test 开头的类用于组织相关的测试用例,并且类中以 test_ 开头的方法被识别为独立的测试用例。请注意,这些方法不能包含 __ init __ 方法。

  • 使用 assert 进行断言: 在 pytest 中,使用 assert 语句进行断言是推荐的做法。例如 assert add(2, 3) == 5 可以用于断言 add() 函数的结果是否符合预期。

三、代码示例

1、测试函数和测试类

# content of test_sample.py
# 测试函数
def func(x):
    return x + 1

def test_answer():
    assert func(3) == 4
# 可以看到pytest自动地运行了test_answer函数,同时提示测试通过,因为func函数的返回值是4


# 测试类,把多条用例放到一个类中
class TestClass:
    def func(self, x):
        return x + 1

    def test_B(self):
        assert self.func(3) == 6, '结果不符合预期'

    def test_A(self):
        assert self.func(3) == 5
# 可以看到,pytest自动地运行了test_B和test_A函数,同时都提示测试失败,\
# 因为TestClass类中的func方法的返回值是4,而不是6和5,所以assert语句报错

在这里插入图片描述

2、参数化测试

# content of test_sample.py
import pytest

@pytest.mark.parametrize("a, b, expected", [
    (2, 3, 5),
    (4, 5, 9),
    (6, 7, 13)
])
def test_addition(a, b, expected):
    assert a + b == expected

通过 @pytest.mark.parametrize 装饰器,指定了要传入 test_addition 函数的参数和预期结果。在这个例子中,我们定义了三组参数 (2, 3, 5)、(4, 5, 9) 和 (6, 7, 13)。

然后,test_addition 函数会依次接收每组参数,并执行断言语句 assert a + b == expected 进行验证。如果断言条件成立,即两数相加等于预期结果,那么测试通过;否则,会触发断言错误,测试失败。
在这里插入图片描述

3、跳过测试

# content of test_sample.py
import pytest

@pytest.mark.skip(reason="Not implemented yet")
def test_multiply():
    assert 3 * 4 == 12

使用@pytest.mark.skip装饰器将其标记为跳过的测试,并提供了一个说明信息"Not implemented yet"

由于该测试函数被标记为跳过,因此在运行测试套件时,这个测试不会被执行。这可以作为一个占位符,表示该测试还没有实现。一旦实现了相应的功能,可以删除@pytest.mark.skip行或注释掉它,以便让测试函数正常运行。
在这里插入图片描述

4、分组和标记

# content of test_sample.py
import pytest

@pytest.mark.group1
def test_addition():
    assert (1 + 2) == 3

@pytest.mark.group1
def test_subtraction():
    assert (5 - 3) == 2

@pytest.mark.group2
@pytest.mark.skip(reason="Not implemented yet")
def test_multiplication():
    assert (2 * 3) == 6

@pytest.mark.group2
def test_division():
    assert (10 / 2) == 5

@pytest.mark.group1和@pytest.mark.group2是自定义标记,可以用来对测试函数进行分组或分类。通过在运行测试时指定标记,可以选择性地运行特定的测试组

例如,可以使用以下命令只运行被标记为group1的测试:

pytest -m group1

这样只会执行test_addition()和test_subtraction()函数,而跳过test_multiplication()和test_division()函数

  • 运行以上示例会有警告信息,这时我们需要把group1 和group2 注册到 pytest 中,在项目目录中创建一个pytest.ini(如果你尚未创建),并在其中定义自定义标记。下面是在pytest.ini 中注册 group1和group2 标记的示例:
[pytest]
markers =
    group1: group1 测试的描述
    group2: group2 测试的描述

在这里插入图片描述

5、异常处理

# content of test_sample.py
import pytest


def divide(a, b):
    if b == 0:
        raise ZeroDivisionError("Cannot divide by zero")
    return a / b


def test_divide():
    with pytest.raises(ZeroDivisionError) as exc_info:
        divide(10, 0)

    assert str(exc_info.value) == "Cannot divide by zero"

在上面的示例中,divide 函数用于执行除法运算。如果除数 b 为零,则会抛出 ZeroDivisionError 异常。在测试函数 test_divide 中,我们使用 pytest.raises 上下文管理器捕获该异常,并断言其异常信息是否与预期相符。

当运行 pytest 命令来执行测试时,它将检测到 divide 函数引发了 ZeroDivisionError 异常,并且断言通过。这表明异常处理机制正常工作。

四、常用的断言方法

assert x == y:判断x是否等于y
assert x != y:判断x是否不等于y
assert x > y:判断x是否大于y
assert x < y:判断x是否小于y
assert x >= y:判断x是否大于等于y
assert x <= y:判断x是否小于等于y
assert x 判断x为真
assert not x 判断x不为真
assert item in collection:判断item是否在collection中
assert item not in collection:判断item是否不在collection中

五、执行命令

1、Pytest执行命令

pytest: 运行所有以test_*.py或*_test.py命名的文件中的测试函数。
pytest test_sample.py: 运行指定的test_sample.py文件中的测试函数。
pytest testing/: 运行指定目录下所有以test_*.py命名的文件中的测试函数。
pytest -k "test_B": 按关键字匹配运行包含test_B关键字的测试函数。
pytest test_sample.py::test_B: 运行指定的test_sample.py文件中的test_B函数。
pytest test_sample.py::TestClass::test_B: 运行指定的test_sample.py文件中的TestClass测试类中的test_B方法。

2、其他执行命令

pytest -q: 使用-q/--quiet标志可以使输出保持简短。
pytest -v: 显示每个测试用例的执行结果。
pytest -s: 用于显示测试函数中的print()函数输出。
pytest -x: 第一次遇到错误后停止测试。
pytest --maxfail=2: 遇到两次错误后停止测试。
pytest -rs: -rs选项可以显示测试报告的摘要,包括已跳过的测试、错误和失败的数量以及原因。

六、目录结构组织

在使用 Pytest 进行单元测试时,你可以按照以下目录结构组织你的测试用例:

project/
├── src/
│   ├── module1.py
│   └── module2.py
└── tests/
    ├── test_module1.py
    └── test_module2.py
  • project/ 是你的项目根目录
  • src/ 目录存放你的源代码文件
  • module1.py 和 module2.py 是你要测试的模块或功能的源代码文件
  • tests/ 目录存放测试用例文件
  • test_module1.py 和 test_module2.py 是用于测试 module1.py 和 module2.py
    的测试用例文件

你可以根据需要在 tests/ 目录下创建更多的测试用例文件,每个文件可以包含多个测试函数。在测试用例文件中,你可以使用 Pytest 提供的各种断言和装饰器来编写测试逻辑。

请注意,这只是一种常见的组织结构示例,你可以根据自己的项目需要进行调整和扩展。

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

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

相关文章

TEE GP(Global Platform)功能认证方案

TEE之GP(Global Platform)认证汇总 一、功能认证介绍 二、功能认证测试套和测试工具 1、“测试套件”是指由GlobalPlatform测试文档、测试脚本和/或其他材料组成的套件&#xff0c;基于给定的GlobalPlatform规范和相关配置&#xff0c;由GlobalPlatform发布&#xff0c;目的是…

【C++】类和对象-对象特性

1.构造函数和析构函数 2.函数的分类以及调用 以后采用括号法 int main() { /******************************************///test01();//test02();Person p;/******************************************/system("pause");return 0; }&#xff08;1&#xff09…

行业追踪,2023-07-27

自动复盘 2023-07-27 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

linux系统下(centos7.9)安装Jenkins全流程

一、卸载历史版本 # rpm卸载 rpm -e jenkins# 检查是否卸载成功 rpm -ql jenkins# 彻底删除残留文件 find / -iname jenkins | xargs -n 1000 rm -rf二、环境依赖安装 yum -y install epel-releaseyum -y install daemonize三、安装Jenkins Jenkins官网传送带&#xff1a; …

【bar堆叠图形绘制】

绘制条形图示例 在数据可视化中&#xff0c;条形图是一种常用的图表类型&#xff0c;用于比较不同类别的数据值。Python的matplotlib库为我们提供了方便易用的功能来绘制条形图。 1. 基本条形图 首先&#xff0c;我们展示如何绘制基本的条形图。假设我们有一个包含十个类别的…

【数据结构】实验四:循环链表

实验四 循环链表 一、实验目的与要求 1&#xff09;熟悉循环链表的类型定义和基本操作&#xff1b; 2&#xff09;灵活应用循环链表解决具体应用问题。 二、实验内容 题目一&#xff1a;有n个小孩围成一圈&#xff0c;给他们从1开始依次编号&#xff0c;从编号为1的小孩开…

写给新手的单元测试框架unittest运行的简单问题

当使用unittest框架编写和运行单元测试时&#xff0c;需要遵循以下步骤&#xff1a; 1、导入unittest模块&#xff1a;在代码中首先导入unittest模块。 import unittest 2、创建测试类&#xff1a;创建一个继承自unittest.TestCase的测试类。该类将包含一系列测试方法。 cla…

#P1006. [NOIP2010普及组] 三国游戏

题目描述 小涵很喜欢电脑游戏&#xff0c;这些天他正在玩一个叫做《三国》的游戏。 在游戏中&#xff0c;小涵和计算机各执一方&#xff0c;组建各自的军队进行对战。游戏中共有 NN 位武将&#xff08;NN为偶数且不小于44&#xff09;&#xff0c;任意两个武将之间有一个“默…

什么是低代码开发平台?它可以实现哪些功能?

什么是低代码开发平台&#xff1f; 低代码来源于英文“Low Code&#xff0c;它意指一种快速开发的方式&#xff0c;使用最少的代码、以最快的速度来交付应用程序。通俗的来说&#xff0c;就是所需代码数量低&#xff0c;开发人员门槛低&#xff0c;操作难度低。一般采用简单的…

模拟实现二叉搜索树

1、TreeSet和TreeMap插入元素时一定要比较大小&#xff0c;因为其底层是红黑树&#xff08;由二叉搜索树调整形成&#xff09;。 2、删除二叉搜索树的目标节点时有三种情况&#xff1a; &#xff08;1&#xff09;cur.leftnull ①cur是root&#xff0c;则rootcur.right ②cur不…

一百多行 C 语言代码实现一个简单异步事件触发机制!

一、简介 QT 中有一种异步处理机制叫做信号和槽函数&#xff0c;通过将信号与槽函数进行绑定连接&#xff0c;后续若该信号触发&#xff0c;会自动调用对应的槽函数。这种机制很适合处理很繁琐的逻辑程序&#xff0c;例如我点击界面的 close 按钮&#xff0c;便触发 close 信号…

基于穷举搜索的AI自动实现俄罗斯方块游戏(核心代码详解)

一、算法思想核心 这个俄罗斯方块AI的核心思想是通过穷举搜索当前形状和下一个形状的所有可能的放置组合&#xff0c;并为每个组合计算一个得分。得分是根据游戏板面的状态来评估每个组合的优劣&#xff0c;最终选择得分最高的放置策略。 具体的实现步骤和核心思想如下&#…

怎么恢复回收站清空的文件,教你三种恢复的方法

不论是笔记本电脑还是台式机电脑&#xff0c;都有回收站这样的“后悔药”&#xff0c;我们许多误删除的文件夹、图片、视频、文档等都能从它里面找到&#xff0c;回收站在灵活运用下能更好地为我们服务&#xff0c;但是使用过程中难免会出现失误&#xff0c;比如说不小心清空了…

pdf合并大小不一样怎么办?有这几个方法就够了

pdf合并大小不一样怎么办&#xff1f;在日常工作和生活中&#xff0c;我们经常需要处理PDF文件。在将多个PDF文件合并成一个时&#xff0c;由于这些文件的大小和格式可能不同&#xff0c;可能会遇到一些问题。但不用担心&#xff0c;接下来将介绍几种方法来解决这个问题。 方法…

JAVA缓存技术介绍

OSCache OSCache是个一个广泛采用的高性能的J2EE缓存框架&#xff0c;OSCache能用于任何Java应用程序的普通的缓存解决方案。 OSCache有以下特点&#xff1a; 我创建了一个群&#xff0c;群里不定期分享技术干货&#xff0c;行业秘闻&#xff0c;汇集各类奇妙好玩的话题和流行动…

Individual household electric power consumption个人家庭用电量数据挖掘与时序预测建模

今天接到一个任务就是需要基于给定的数据集来进行数据挖掘分析相关的计算&#xff0c;并完成对未来时段内数据的预测建模&#xff0c;话不多少直接看内容。 官方数据详情介绍在这里&#xff0c;如下所示&#xff1a; 数据集中一共包含9个不同的字段&#xff0c;详情如下&#…

MinIO对象存储

MinIO 是一个高性能的分布式对象存储系统。 它是软件定义的&#xff0c;在行业标准硬件上运行&#xff0c;并且 100% 开源&#xff0c;主要许可证是 GNU AGPL v3。 MinIO 的不同之处在于它从一开始就被设计为私有/混合云对象存储的标准。 因为 MinIO 是专门为对象而构建的&…

day14 | 100.二叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数

文章目录 一、二叉树的最大深度二、二叉树的最小深度三、完全二叉树的节点数 一、二叉树的最大深度 100.二叉树的最大深度 因为题给出的高度和深度是一样的&#xff0c;所以求得结果都能过。 class Solution { public:int getHeight(TreeNode *node){if (node nullptr)retu…

Qt 第三讲 手动拖动ui界面组件,事件处理机制,实现简单闹钟

手动拖动ui界面组件&#xff0c;实现闹钟 源文件 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->btn_end->setEnabled(false);speecher new QTex…

Linux基础内容(29)—— 额外锁

Linux基础内容&#xff08;28&#xff09;—— POSIX信号量与循环队列_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131844590?spm1001.2014.3001.5501 目录 1.其他常见的各种锁 自旋锁 库语言的实现 2.读者写者问题 1.读者写者线程 2.…