Pytest 基础概念

以下是 Pytest 测试框架的 基础概念 整理,涵盖其核心设计、关键术语和基本用法:

1. 核心设计理念

  • 简洁易用:通过简单的断言和自动测试发现,降低测试代码复杂度。
  • 可扩展性:通过插件系统和钩子函数(Hooks)支持高度定制。
  • 明确反馈:提供清晰的错误报告,快速定位问题。

2. 安装与运行

2.1 安装

pip install pytest

2.2 运行测试

pytest [文件或目录路径]  # 默认运行当前目录下所有测试

常用选项

  • -v:显示详细输出。
  • -k <表达式>:按名称匹配运行特定测试(如 -k "test_login")。
  • -m <标记>:运行指定标记的测试(如 -m smoke)。
  • --collect-only:仅列出可被发现的测试(不执行)。

3. 测试发现规则

Pytest 自动发现测试代码,规则如下:

  1. 文件匹配:文件名以 test_ 开头或结尾(如 test_*.py 或 *_test.py)。
  2. 测试对象:函数名以 test_ 开头的函数。类名以 Test 开头的类中的方法(方法名以 test_ 开头)。
# test_example.py
def test_add():          # 会被识别为测试
    assert 1 + 1 == 2

class TestMath:          # 测试类
    def test_multiply(self):  # 会被识别为测试
        assert 2 * 3 == 6

4. 断言机制

  • 使用原生 assert 语句,无需额外断言方法。
  • 失败时自动输出详细上下文(如变量值)。
def test_string():
    s = "hello"
    assert s.upper() == "HELLO"  # 失败时会显示 s.upper() 的实际值

5. 测试用例参数化

使用 @pytest.mark.parametrize 为单个测试函数提供多组输入数据,生成多个测试用例。

import pytest

@pytest.mark.parametrize("a, b, expected", [
    (1, 2, 3),
    (5, -3, 2),
    (0, 0, 0),
])
def test_addition(a, b, expected):
    assert a + b == expected

此测试会生成 3 个独立的测试用例。

6. 标记(Markers)

用于分类测试或附加元数据,常见用途:

  • 跳过测试:@pytest.mark.skip(reason="...")
  • 预期失败:@pytest.mark.xfail
  • 自定义标记:@pytest.mark.smoke(需在 pytest.ini 中注册)
@pytest.mark.skip(reason="功能暂未实现")
def test_unimplemented():
    ...

@pytest.mark.smoke
def test_login():
    ...

7. 配置文件(pytest.ini)

用于全局配置 pytest 行为,例如:

[pytest]
addopts = -v -m "not slow"  # 默认命令行选项
markers =
    slow: marks tests as slow
    smoke: quick validation tests
testpaths = tests/          # 指定测试目录

8. 临时文件与目录

使用内置 Fixture 管理临时资源:

  • tmp_path:生成临时目录(返回 pathlib.Path 对象)。
  • tmpdir:生成临时目录(返回 py.path.local 对象,旧版)。
def test_temp_file(tmp_path):
    file = tmp_path / "test.txt"
    file.write_text("data")
    assert file.read_text() == "data"

9. 插件系统

  • 内置插件:如 pytest-cov(覆盖率)、pytest-xdist(并行测试)。
  • 自定义插件:通过编写钩子函数或 Fixture 扩展功能。

安装插件

pip install pytest-<插件名>

10. 与 unittest 兼容

Pytest 可以直接运行基于 unittest 编写的测试,并支持混合使用两种风格的测试代码。

import unittest

class TestLegacy(unittest.TestCase):
    def test_old_style(self):
        self.assertEqual(2 * 3, 6)

11. 常见问题与技巧

11.1 测试文件组织

推荐目录结构:

project/
├── src/          # 源代码
└── tests/        # 测试代码
    ├── conftest.py
    ├── test_math.py
    └── test_api.py

11.2 断言异常

使用 pytest.raises 捕获预期异常:

def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        1 / 0

11.3 调试测试

在失败时启动调试器:

pytest --pdb  # 测试失败时进入 pdb 调试

总结

Pytest 通过简洁的语法、灵活的扩展机制和强大的断言系统,成为 Python 生态中最流行的测试框架。

进阶高级测试工程师 文章被收录于专栏

《高级软件测试工程师》专栏旨在为测试领域的从业者提供深入的知识和实践指导,帮助大家从基础的测试技能迈向高级测试专家的行列。 在本专栏中,主要涵盖的内容: 1. 如何设计和实施高效的测试策略; 2. 掌握自动化测试、性能测试和安全测试的核心技术; 3. 深入理解测试驱动开发(TDD)和行为驱动开发(BDD)的实践方法; 4. 测试团队的管理和协作能力。 ——For.Heart

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务