pytest介绍(python测试框架)(@pytest.mark.parametrize、@pytest.fixtures)

发布于:2025-08-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

文章目录


pytest 是 Python 中最流行且功能强大的测试框架之一,以其简洁的语法、灵活的功能和强大的扩展性著称。它适用于从简单的单元测试到复杂的自动化测试场景,广泛用于开发、测试和持续集成流程中。以下是关于 pytest 的详细介绍:


1. 核心特点

- 简洁易用:无需复杂的配置,只需编写简单的函数或类即可进行测试。

- 丰富的断言:直接使用 Python 内置的 assert 语句,失败时提供详细的错误信息。

- 自动发现测试:通过约定的命名规则(如 test_*.py*_test.py)自动收集测试用例。

- 参数化测试:通过 @pytest.mark.parametrize 轻松实现多组输入和输出的测试。

- Fixtures 管理资源:通过 fixture 定义测试的前置条件和后置清理逻辑,支持重用和作用域控制。

- 插件生态:丰富的插件(如 pytest-html 生成报告、pytest-xdist 并行执行)扩展功能。

- 模块化测试:支持测试函数、测试类、测试方法等多种组织形式。


2. 安装与快速入门

安装

pip install pytest

编写第一个测试

创建一个文件 test_sample.py

def add(x, y):
    return x + y

def test_add():
    assert add(1, 2) == 3  # 断言

运行测试

在命令行中执行:

pytest test_sample.py

输出示例:

=========================== test session starts ============================
collected 1 item

test_sample.py .                                                    [100%]

============================ 1 passed in 0.01s =============================

3. 核心功能详解

3.1 测试函数与类

- 测试函数:以 test_ 开头的函数。

- 测试类:以 Test 开头的类,类中的方法以 test_ 开头。

class TestMath:
    def test_add(self):
        assert 1 + 1 == 2

    def test_subtract(self):
        assert 3 - 1 == 2

3.2 参数化测试

使用 @pytest.mark.parametrize 实现多组输入测试:

import pytest

@pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (4, 5, 9), (7, 8, 15)])
def test_add(a, b, expected):
    assert a + b == expected

3.3 Fixtures(固定装置)

Fixtures 用于管理测试的前置条件(如初始化资源)和后置清理(如关闭连接)。通过装饰器 @pytest.fixture 定义:

代码示例

import pytest

@pytest.fixture
def tmp_dir(tmpdir):  # 使用内置的 tmpdir fixture
    return tmpdir.mkdir("test_data")

def test_tmp_dir(tmp_dir):
    file = tmp_dir.join("test.txt")
    file.write("Hello")
    assert file.read() == "Hello"

上述代码具体解释参见:pytest tmpdir fixture介绍(tmpdir_factory)(自动在测试开始前创建一个临时目录,并在测试结束后删除该目录)

Fixtures 的作用域

  • function(默认):每个测试函数执行一次。
  • class:每个测试类执行一次。
  • module:每个模块执行一次。
  • session:整个测试会话执行一次。

3.4 异常测试

测试是否抛出特定异常:

def test_exception():
    with pytest.raises(ValueError):
        raise ValueError("Invalid input")

3.5 插件系统

通过插件扩展功能:

- 生成 HTML 报告pytest-html

pytest --html=report.html

- 并行执行pytest-xdist

pytest -n 4  # 使用 4 个 CPU 并行运行

3.6 命令行参数

- -v:显示详细输出。

- -k:按关键字过滤测试(如 pytest -k "add or subtract")。

- -m:按标记运行测试(如 pytest -m slow)。

- --maxfail:达到指定失败次数后停止测试。


4. 高级用法

4.1 标记测试(Markers)

为测试添加标签,用于分类或过滤:

import pytest

@pytest.mark.slow
def test_slow():
    assert 1 + 1 == 2

运行标记为 slow 的测试:

pytest -m slow

4.2 Hook 函数

通过钩子函数(Hook)自定义测试流程,例如修改测试报告或收集用例逻辑。需在 conftest.py 中定义。

4.3 多进程/分布式测试

结合 pytest-xdist 插件实现多进程或分布式测试,提升执行效率。

4.4 模拟对象(Mock)

使用 unittest.mock 模块模拟函数或对象行为:

from unittest.mock import Mock

def test_mock():
    mock = Mock(return_value=42)
    assert mock() == 42

5. 实际应用场景

- 单元测试:验证单个函数或方法的正确性。

- 集成测试:测试多个模块或系统的协作。

- API 测试:结合 requests 等库测试 HTTP 接口。

- 持续集成(CI/CD):集成到 Jenkins、GitHub Actions 等工具中,自动化运行测试。


6. 优势总结

  • 学习成本低:语法简单,无需继承基类。
  • 可扩展性强:丰富的插件生态支持各种需求。
  • 社区活跃:文档完善,社区支持强大。
  • 高效调试:失败时自动显示详细的错误信息和中间值。

7. 学习资源

通过掌握 pytest,你可以显著提升 Python 项目的测试效率和代码质量!


网站公告

今日签到

点亮在社区的每一天
去签到