> 技术文档 > pytest官方Tutorial所有示例详解(一)

pytest官方Tutorial所有示例详解(一)

以下是对 ​pytest 官方 Tutorial​ 的详细解析,结合代码示例和关键概念说明,帮助你逐步掌握 pytest 的核心功能。


1. 安装与运行第一个测试

安装

pip install -U pytest

验证安装:

pytest --version

第一个测试文件

创建文件 test_sample.py

# test_sample.pydef func(x): return x + 1def test_func(): assert func(3) == 4 # 断言:验证 func(3) 的结果是否为 4

运行测试

pytest test_sample.py

输出解析​:

  • pytest 会自动发现以 test_ 开头的文件(如 test_sample.py)和函数(如 test_func)。
  • 若断言失败,会显示详细的错误信息(如实际值和期望值的差异)。

2. 断言(Assertions)​

pytest 直接使用 Python 的 assert 语句,无需复杂的断言方法。例如:

def test_integers(): a = 5 b = 6 assert a + 1 == b # 验证 a+1 是否等于 bdef test_strings(): s = \"hello\" assert s.upper() == \"HELLO\" # 验证字符串大写转换

关键点​:

  • 断言失败时,pytest 会显示失败的具体表达式(如 assert 5 + 1 == 7 会明确提示 6 != 7)。

3. 测试类(Test Classes)​

将相关测试组织到类中,类名需以 Test 开头,方法名以 test_ 开头:

# test_class.pyclass TestClass: def test_one(self): x = \"this\" assert \"h\" in x # 验证字符串包含字符 \'h\' def test_two(self): x = \"hello\" assert hasattr(x, \"check\") # 验证对象是否有 \'check\' 属性(预期失败)

运行方式​:

pytest test_class.py -v # -v 显示详细输出

输出示例​:

test_class.py::TestClass::test_one PASSEDtest_class.py::TestClass::test_two FAILED

4. 跳过测试(Skipping Tests)​

使用 @pytest.mark.skip 跳过特定测试:

# test_skip.pyimport pytest@pytest.mark.skip(reason=\"暂时跳过此测试\")def test_skip_example(): assert False # 此测试会被跳过,不会执行

运行结果​:

test_skip.py::test_skip_example SKIPPED (暂时跳过此测试)

5. 参数化测试(Parametrization)​

通过 @pytest.mark.parametrize 对同一测试函数传入多组参数:

# test_parametrize.pyimport pytest@pytest.mark.parametrize(\"a, b, expected\", [ (1, 2, 3), (4, 5, 9), (10, 20, 30),])def test_add(a, b, expected): assert a + b == expected

运行结果​:

test_parametrize.py::test_add[1-2-3] PASSEDtest_parametrize.py::test_add[4-5-9] PASSEDtest_parametrize.py::test_add[10-20-30] PASSED

优势​:避免重复代码,覆盖多组输入场景。


6. Fixture(测试夹具)​

Fixture 用于提供测试所需的资源(如数据库连接、临时文件等),通过 @pytest.fixture 定义:

# test_fixture.pyimport pytest@pytest.fixturedef sample_data(): return [1, 2, 3] # 提供测试数据def test_sum(sample_data): assert sum(sample_data) == 6 # 使用 fixture 提供的数据

运行方式​:

pytest test_fixture.py -v

关键点​:

  • Fixture 可以跨多个测试函数复用。
  • 支持作用域(如 scope=\"module\" 表示整个模块共享一个 Fixture 实例)。

7. 临时目录与文件(tmp_path Fixture)​

pytest 内置 tmp_path Fixture,用于创建临时目录和文件:

# test_tmp_path.pydef test_create_file(tmp_path): d = tmp_path / \"subdir\" # 创建子目录 d.mkdir() p = d / \"hello.txt\" # 创建文件 p.write_text(\"Hello, pytest!\") assert p.read_text() == \"Hello, pytest!\" assert len(list(tmp_path.iterdir())) == 1 # 验证目录内容

用途​:测试文件操作时无需清理临时文件。


8. 捕获异常(Exception Testing)​

使用 pytest.raises 验证代码是否抛出预期异常:

# test_exception.pyimport pytestdef test_zero_division(): with pytest.raises(ZeroDivisionError): # 验证是否抛出 ZeroDivisionError 1 / 0

扩展​:还可检查异常的具体信息:

with pytest.raises(ValueError) as excinfo: int(\"xyz\")assert \"invalid literal\" in str(excinfo.value)

9. 标记(Markers)​

通过标记(如 @pytest.mark.slow)分类测试,选择性运行:

# test_markers.pyimport pytest@pytest.mark.slowdef test_slow_function(): import time time.sleep(2) assert True# 运行时指定标记# pytest -m slow # 仅运行标记为 slow 的测试# pytest -m \"not slow\" # 排除 slow 测试

10. 配置文件(pytest.ini)​

通过配置文件 pytest.ini 自定义 pytest 行为(如设置默认命令行选项):

# pytest.ini[pytest]addopts = -v -ra # 默认启用详细输出 (-v) 和失败重试 (-ra)testpaths = tests # 指定测试目录