pytest在python 3.12下开箱即用,只需版本≥8.0.0;真正影响运行的是命名规范(test_.py或_test.py)、目录结构(tests/需含__init__.py)、fixture作用域与注入方式、参数化ids缺失及运行命令明确性等“看不见的规则”。

pytest 在 Python 3.12 下开箱即用,只要版本 ≥8.0.0 就完全兼容——不需要降级解释器,也不需要额外打补丁。真正卡住人的,往往是命名、路径和作用域这些“看不见的规则”。
test_*.py 文件不被发现?检查命名和目录结构
pytest 默认只扫描满足以下任一条件的文件:test_*.py 或 *_test.py。它不会自动递归进空目录或隐藏目录。
- 确保测试文件名严格符合规范,比如
test_login.py可以,login_test.py不行(结尾必须是_test.py,不是test.py) - 如果测试放在
tests/子目录下,该目录必须包含__init__.py(哪怕为空),否则旧版 pytest(如 8.0 之前)可能跳过整个目录 - CI 环境(如 Alpine 容器)中,若遇到模块导入失败,优先检查是否漏了
__init__.py,而不是急着改 PYTHONPATH
conftest.py 里的 fixture 在 TestClass 里不生效?看 scope 和注入方式
fixture 不是全局变量,它依赖显式声明的作用域和调用方式。写成 self.client 却没在参数列表里接收,就会静默失效。
- function 级 fixture(默认)只能通过函数参数注入:
def test_something(self, api_client):,不能靠self.api_client访问 - 想在类内统一 setup,用
@pytest.fixture(autouse=True, scope="function"),但要小心:autouse 容易掩盖真实依赖,调试时反而更难定位问题 - class 级 fixture 需显式声明
scope="class",且必须作为方法参数传入,pytest 不会自动绑定到self
参数化测试显示 test_xxx[0] 而不是可读名称?必须加 ids
pytest 默认用参数元组索引(如 [0])生成用例 ID,这对调试和报告极其不友好。中文乱码通常不是编码问题,而是 ID 缺失导致报告系统 fallback 到默认标识。
- 参数化时务必显式提供
ids:@pytest.mark.parametrize("url,expected", [("a.com", 200)], ids=["valid_domain"]) - 生成 HTML 报告时加上
--charset=utf-8参数,避免 Windows 控制台 GBK 环境污染 HTML 内联 JS - CI 容器中若仍乱码,启动命令加
ENV PYTHONIOENCODING=utf-8,比改 locale 更直接有效
运行命令怎么写才不踩坑?别依赖默认行为
直接敲 pytest 看似方便,但容易因当前路径、配置文件缺失或隐式插件干扰而行为不一致。
- 明确指定入口:
pytest tests/ -v比pytest更可控;加-v能立刻看到用例全名,方便核对是否加载正确 - 跳过某些目录用
--ignore=venv或--ignore=__pycache__,避免因临时文件触发意外 import 错误 - 调试单个用例最快方式:
pytest tests/test_auth.py::TestLogin::test_login_success -s,-s保留 print 输出,::语法支持文件→类→方法三级定位
ids、或者测试目录缺了那个不起眼的 __init__.py。这些点一旦漏掉,现象往往很隐蔽:用例“没跑”“跳过”“静默失败”,花半天时间查环境变量反而南辕北辙。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











