pytest默认只识别test_.py和_test.py文件,这是源码硬编码规则;修改python_files仅覆盖而非扩展该列表,误配会导致扫描异常或性能下降。

pytest 默认只识别 test_*.py 和 *_test.py 两类文件名,这是硬编码规则,不是配置项可随意绕过的。
pytest 文件发现规则是写死的,不是靠配置驱动
它在源码里直接定义了两个 glob 模式:test_*.py 和 *_test.py。哪怕你改了 python_files 配置,也只是覆盖这个列表——但如果你写成 python_files = ["*.py"],它就真的会扫所有 .py 文件,包括 __init__.py、main.py,甚至你项目里的 setup.py,然后报一堆导入错误或跳过非测试函数。
常见误操作:
- 以为加个
@pytest.mark.test就能让任意文件被识别——不行,标记只影响已发现的测试项,不参与“发现”阶段 - 把文件命名为
math_tests.py或test.py——前者不匹配*_test.py(少了个下划线),后者不匹配test_*.py(缺后缀) - 在
pyproject.toml里写了python_files = "test_*.py"却没加方括号——必须是数组:python_files = ["test_*.py"],否则配置无效
为什么不能直接支持 test_*.py 以外的命名?
因为 pytest 的发现逻辑依赖“快速排除”,避免扫描无关文件。如果放开到任意命名,就得逐个打开、解析 AST 判断是否含 def test_,性能下降明显,尤其在大型项目中。
实际影响:
- CI 环境里,
pytest tests/能跑通,但pytest .可能漏掉某些子目录——因为那些目录没被递归进搜索路径,除非有__init__.py或显式指定 - VSCode 测试面板不显示用例,大概率是工作目录不对,或者
python.testing.cwd指向了src/而不是项目根目录 - PyCharm 默认用
unittestrunner,即使装了 pytest 也不会触发它的发现逻辑——得手动切到pytest模式
临时绕过命名限制的实操方式
真有历史原因必须用 my_tests.py 这类名字?可以用 -k 或 --pyargs 强制加载,但代价是失去自动发现能力:
-
pytest my_tests.py -k "test_":强制运行该文件,再用关键字过滤函数名 -
python -m pytest --pyargs my_tests:前提是my_tests.py已安装为可导入模块(即在sys.path里,且无语法错误) - 最稳妥的是重命名:
mv my_tests.py test_my_tests.py,一劳永逸
别指望删 __pycache__ 或重启 IDE 能解决命名问题——那是缓存或路径问题的补救手段,不是根本解法。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











