一、先搞懂:pytest 是什么?

pytest 是 Python 中最流行的单元测试框架,比 Python 自带的unittest更简洁、更强大,支持自动化测试、参数化、失败重试、集成第三方插件等,是职场中做 Python 开发 / 测试的必备技能。

二、第一步:环境搭建(零基础也能搞定)

1. 安装 pytest

确保你的电脑已经安装了 Python(推荐 3.7 + 版本),打开 CMD / 终端,执行:

pip install pytest

验证安装是否成功:

pytest --version  # 输出pytest x.x.x即为成功
2. 目录结构(新手标准写法)

先创建一个简单的项目结构,后续所有代码都按这个结构来:

pytest_demo/          # 项目根目录
├── calc.py           # 待测试的业务代码文件
└── test_calc.py      # 测试用例文件(必须以test_开头)

三、第二步:写第一个 pytest 用例(核心入门)

1. 先写业务代码

calc.py中写一个简单的加减函数(作为测试对象):

# calc.py
def add(a, b):
    """加法函数"""
    return a + b

def sub(a, b):
    """减法函数"""
    return a - b
2. 写测试用例

test_calc.py中写测试用例(pytest 的核心规则要记牢):

# test_calc.py
from calc import add, sub

# 测试函数必须以test_开头
def test_add():
    # 断言:判断add(1,2)的结果是否等于3
    assert add(1, 2) == 3  # 断言成功:用例通过
    assert add(0, 0) == 0  # 多个断言,全部成功才通过

def test_sub():
    assert sub(5, 3) == 2
    assert sub(1, 1) == 0
    # 故意写一个失败的断言,看看效果
    # assert sub(2, 1) == 0
3. 运行测试用例

打开终端,进入pytest_demo目录,执行:

# 基础运行:会自动查找所有test_开头的文件/函数
pytest
# 详细输出运行结果(推荐新手用)
pytest -v
# 只运行指定文件
pytest test_calc.py -v
# 只运行指定函数
pytest test_calc.py::test_add -v
4. 运行结果解读(新手必看)
  • .:表示 1 个用例通过
  • F:表示 1 个用例失败
  • E:表示 1 个用例报错
  • 终端最后会显示总用例数、通过数、失败数、耗时

四、第三步:核心知识点(新手高频用)

1. 断言(测试的核心)

pytest 直接用 Python 原生的assert断言,比 unittest 的self.assertEqual更简洁:

断言场景 pytest 写法 说明
判断相等 assert a == b a 等于 b 则通过
判断不等 assert a != b a 不等于 b 则通过
判断包含 assert "abc" in "abc123" 包含则通过
判断布尔 assert True 为 True 则通过
断言异常 pytest.raises(异常类型) 捕获指定异常则通过

断言异常示例

def test_div():
    def div(a, b):
        return a / b
    
    # 断言除以0会抛出ZeroDivisionError
    with pytest.raises(ZeroDivisionError):
        div(1, 0)
2. 参数化(批量测试,减少重复代码)

如果要测试多组数据,不用写多个 test 函数,用@pytest.mark.parametrize

import pytest
from calc import add

# 参数化:(输入1, 输入2, 预期结果)
@pytest.mark.parametrize("a, b, expected", [
    (1, 2, 3),    # 用例1
    (0, 0, 0),    # 用例2
    (-1, 1, 0),   # 用例3
    (2.5, 3.5, 6) # 用例4
])
def test_add_param(a, b, expected):
    assert add(a, b) == expected

运行后会自动执行 4 个用例,逐个验证。

3. 前置 / 后置操作(测试前后的准备 / 清理)

比如测试前初始化数据,测试后清理文件,pytest 提供 3 种常用方式:

作用范围 装饰器 说明
函数级 @pytest.fixture 每个测试函数执行前 / 后运行
类级 setup_class/teardown_class 测试类中所有函数执行前 / 后各运行一次
模块级 setup_module/teardown_module 整个.py 文件执行前 / 后各运行一次

最常用的 fixture 示例

import pytest

# 定义fixture:测试前初始化数据
@pytest.fixture
def init_data():
    print("\n测试前:初始化数据")
    data = [1, 2, 3]
    yield data  # yield之前是前置,之后是后置
    print("\n测试后:清理数据")
    data.clear()

# 使用fixture
def test_use_fixture(init_data):
    assert len(init_data) == 3
    init_data.append(4)
    assert len(init_data) == 4

五、第四步:实战小案例(巩固所学)

需求:测试一个 “判断是否为质数” 的函数,覆盖正常 / 边界 / 异常场景。

# prime.py
def is_prime(n):
    """判断是否为质数:大于1的自然数,只能被1和自身整除"""
    if not isinstance(n, int):
        raise TypeError("必须输入整数")
    if n <= 1:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

# test_prime.py
import pytest
from prime import is_prime

# 参数化测试多组场景
@pytest.mark.parametrize("num, expected", [
    (2, True),    # 最小质数
    (3, True),    # 质数
    (4, False),   # 非质数
    (1, False),   # 边界值(小于2)
    (0, False),   # 边界值
    (-5, False),  # 负数
])
def test_is_prime(num, expected):
    assert is_prime(num) == expected

# 测试异常场景
def test_is_prime_error():
    with pytest.raises(TypeError):
        is_prime(3.5)  # 输入浮点数,应抛出异常

运行命令:pytest test_prime.py -v,验证所有用例是否通过。

六、新手避坑指南

  1. 文件名 / 函数名规则:测试文件必须以test_开头,测试函数 / 类也必须以test_开头(pytest 才会识别);
  2. 中文乱码问题:运行时加-s参数(pytest -v -s),并确保文件编码为 UTF-8;
  3. 依赖缺失:如果提示ModuleNotFoundError,先检查是否安装对应包,或把项目目录加入 Python 路径;
  4. 跳过用例:用@pytest.mark.skip(reason="暂时跳过")可以临时跳过某个用例。

总结

  1. pytest 核心优势是简洁、灵活,新手先掌握「test_命名规则 + assert 断言 + 参数化 + fixture」这 4 个基础;
  2. 学习路径:先写简单用例→掌握核心语法→结合实战场景→学习插件(如 pytest-html 生成测试报告);
  3. 运行命令记住 3 个常用参数:-v(详细输出)、-s(显示打印内容)、-k(按关键字筛选用例)。
Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐