10 分钟跑通第一个测试:pytest 入门完整教程
【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytest
pytest 是一款 Python 测试框架:你用普通的 assert 语句写断言,它在命令行里自动收集、运行所有测试,并把失败位置打印得清清楚楚。这篇 pytest 教程会带你完成安装、写出第一个测试,再掌握 fixtures、参数化、标记三个高频技巧,10 分钟即可上手。
为什么需要 pytest 这样的测试框架
以前你可能靠 print 和手动调用来验证函数:改了一行代码,就说不清哪些行为被改坏了。测试点一多,靠人脑记住"哪些地方该保持不变"越来越吃力。pytest 把断言、运行、报告合并成一条命令的事,回归验证不再靠手气。
⚡ 用 pip 安装 pytest 并运行第一个测试
打开终端,一条命令完成 pytest 安装:
pip install pytest新建test_quick.py,把被测函数和测试写在同一个文件里。记住两条命名约定:文件名和测试函数都以test_开头,pytest 靠这个规则发现测试。
def add(a, b): return a + b def test_add(): assert add(2, 3) == 5运行:
pytest test_quick.py -v预期看到:
test_quick.py::test_add PASSED ========================= 1 passed in 0.01s =========================绿色 PASSED 说明断言成立,测试通过。
pytest 入门实战:给密码校验工具写测试
换个完整一点的场景:你写了个密码强度检查函数——至少 8 位、含数字、含大写字母才算合格。被测代码password.py:
def is_strong_password(pwd): return ( len(pwd) >= 8 and any(c.isdigit() for c in pwd) and any(c.isupper() for c in pwd) )测试文件test_password.py,覆盖合格、过短、无数字三种情况:
from password import is_strong_password def test_ok(): assert is_strong_password("Abc12345") def test_too_short(): assert not is_strong_password("Ab1") def test_no_digit(): assert not is_strong_password("Abcdefgh")运行pytest,三条用例全过:
test_password.py::test_ok PASSED test_password.py::test_too_short PASSED test_password.py::test_no_digit PASSED ========================= 3 passed in 0.01s =========================想进一步理解 assert 背后的断言重写机制,可以翻看 pytest 官方文档。
🧩 三个让你少写代码的 pytest 技巧
用 pytest fixtures 管理测试前置准备
fixtures(固件)是"可复用的准备步骤":把公共准备代码写成 fixture 函数,测试函数的参数与它同名,pytest 就会自动调用并把结果传进来。
import pytest @pytest.fixture def sample_list(): return [1, 2, 3] def test_sum(sample_list): assert sum(sample_list) == 6以后任何测试想拿这份数据,声明同名参数即可,不必重复造数据。
pytest 参数化测试怎么写
同一个函数要验证多组输入时,不必复制粘贴一堆用例。parametrize 用一行装饰器把多组参数展开,每组独立运行、独立报告,失败时直接知道是哪组输入出的问题。
import pytest def add(a, b): return a + b @pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (0, 5, 5), (-1, 1, 0)]) def test_add(a, b, expected): assert add(a, b) == expected给测试打标记(Markers)则用于筛选运行范围。比如给耗时用例标上@pytest.mark.slow:
import pytest @pytest.mark.slow def test_render_report(): assert True终端执行pytest -m "not slow"就能跳过它,适合"先快速反馈、再跑全量"的场景。
常用 pytest 插件推荐
把测试用顺手之后,这些插件能解决下一层问题:
- pytest-cov:统计测试覆盖了多少代码,输出覆盖率报告
- pytest-mock:向测试注入 mock 对象,隔离数据库、网络等外部依赖
- pytest-xdist:把测试拆到多个进程并行运行,压缩大规模用例的总耗时
- pytest-django:为 Django 项目提供数据库和请求环境支持
- pytest-asyncio:让 pytest 能运行 async def 编写的异步测试函数
❓ pytest 新手常见问题
- 为什么我的测试没被收集?文件名和函数名都要以
test_开头,两条同时满足才会被发现。 - 只想跑某一个测试怎么办?用
::精确定位,例如pytest test_password.py::test_ok。 - 每个文件都要 import pytest 吗?不是,只在用 fixtures、parametrize、mark 等功能时才需要导入。
【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytest
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考