Python pytest 快速入门:第一个测试用例这样写

小飞兽 Python 14 次阅读 2026-07-24

Introduction

写 Python 代码最怕的是什么?改动一个函数,牵一发动全身,不知道哪里炸了。自动化测试就是解决这个问题的——写一次,每次改代码自动跑一遍,有问题立刻发现。

pytest 是 Python 生态里最流行的测试框架,它简洁、强大、生态丰富。本文从零开始,手把手写出第一个 pytest 测试用例,覆盖安装、断言、fixtures 和参数化测试。

---

基础语法

1. 安装 pytest

pip install pytest

验证安装成功:

pytest --version
# pytest 8.0.0

2. 第一个测试用例

项目结构:

myproject/
├── test_sample.py
└── sample.py

# sample.py
def add(a, b):
    return a + b
# test_sample.py
import pytest
from sample import add

def test_add_positive():
    assert add(1, 2) == 3

def test_add_negative():
    assert add(-1, -2) == -3

def test_add_mixed():
    assert add(10, -5) == 5

运行测试:

pytest test_sample.py -v

输出:

test_sample.py::test_add_positive PASSED
test_sample.py::test_add_negative PASSED
test_sample.py::test_add_mixed PASSED

3. 常用断言

pytest 基于 Python 内置 assert,但提供了更友好的错误提示:

def test_assertions():
    # 相等断言
    assert 1 + 1 == 2

    # 不等断言
    assert 3 != 4

    # 布尔断言
    assert True
    assert not False

    # 浮点数精度(用 approx 避免精度问题)
    from pytest import approx
    assert 0.1 + 0.2 == approx(0.3)

    # 成员断言
    assert "py" in "pytest"

    # 异常断言
    with pytest.raises(ZeroDivisionError):
        1 / 0

4. pytest fixtures(测试夹具)

fixtures 负责测试前后的准备工作,比如连接数据库、创建测试文件:

import pytest
import tempfile
import os

@pytest.fixture
def temp_file():
    """创建临时文件,测试结束后自动清理"""
    fd, path = tempfile.mkstemp()
    yield path  # 测试代码在这里执行
    os.close(fd)
    os.unlink(path)

def test_write_file(temp_file):
    with open(temp_file, "w") as f:
        f.write("hello pytest")
    with open(temp_file) as f:
        assert f.read() == "hello pytest"

5. 参数化测试

同一个测试逻辑,用不同参数跑多遍:

import pytest

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

运行结果:

test_add[1-2-3] PASSED
test_add[0-0-0] PASSED
test_add[-1-1-0] PASSED
test_add[-5--3--8] PASSED

---

运行效果

控制台输出(-v 详细模式)

========================= test session starts ==========================
collected 4 items

test_sample.py::test_add_positive PASSED                          [ 25%]
test_sample.py::test_add_negative PASSED                          [ 50%]
test_sample.py::test_add_mixed PASSED                            [ 75%]
test_sample.py::test_assertions PASSED                           [100%]

========================== 4 passed in 0.05s ==========================

HTML 报告(需安装 pytest-html)

pip install pytest-html
pytest --html=report.html

---

常见问题与注意事项

Q1: 测试文件命名不规范?

pytest 默认规则:
  • <code>test_*.py</code> — 所有以 <code>test_</code> 开头的文件
  • <code>*_test.py</code> — 所有以 <code>_test.py</code> 结尾的文件
  • 文件内 <code>test_*</code> 开头的函数自动被识别为测试用例

Q2: 只想跑某个测试函数?

pytest test_sample.py::test_add_positive

Q3: 某个测试暂时跳过?

@pytest.mark.skip(reason="功能开发中")
def test_future_feature():
    pass

Q4: fixture 不生效?

fixture 必须作为测试函数的参数传入,且函数名与 fixture 名称一致。

---

延伸阅读

  • [[pytest 参数化测试详解]] — 多组数据驱动测试
  • [[pytest Fixtures 进阶]] — scope、共享fixture、autouse
  • [[Selenium 浏览器自动化测试]] — Web UI 测试实战
  • [[Python 单元测试完全指南]] — unittest vs pytest 对比

---
有问题欢迎在评论区交流!