pytest 跑测试时 iTerm2 不停弹通知,关闭 terminalprogress 就能止住
pytest 的终端进度控制序列可能被 iTerm2 解释为桌面通知。关闭 terminalprogress,并检查 tox、Docker 的配置入口与版本检测边界。
pytest 跑测试时 iTerm2 不停弹通知,关闭 terminalprogress 就能止住
pytest 9.0.0 在终端中运行时新增了测试进度提示。在 iTerm2 3.6.5 上,这些提示可能变成一连串桌面通知。通知内容如果像 4;... 这样的数字片段,而且随着测试执行不断出现,可以先关闭 terminalprogress 插件:
python -m pytest -p no:terminalprogress
它关闭的是发给终端的额外进度信号,普通测试结果、失败回溯和控制台进度仍会输出。pytest 9.0.0 与 iTerm2 3.6.5 会触发这类通知;通过 tox 或 Docker 运行时,单纯升级到 9.0.1 有时仍会遇到。
原因在终端控制序列的解释方式。pytest 发出 OSC 9;4 表示进度,一些终端版本却把它理解为通知命令,把参数当成通知正文。因此,测试代码不必真的调用系统通知接口,也不一定是某个测试在发送消息。清缓存或调整测试断言通常不会改变这条输出链路。
把设置放进实际测试入口
如果同一项目每次运行都出现,可以将关闭选项加入已有配置。下面是 pytest.ini 示例:
[pytest]
addopts = -p no:terminalprogress
项目原来有 addopts 时,应把该参数追加到原值,保留覆盖率、marker 和其他已有选项。如果使用 pyproject.toml 的 INI 兼容配置,可写为:
[tool.pytest.ini_options]
addopts = "-p no:terminalprogress"
两种格式按项目现有配置选择,不要为了这个问题再添加一个配置文件,让 pytest 选到意外的配置。一次性的本地运行也可以设置 PYTEST_ADDOPTS,但已有该环境变量时同样要合并内容,避免覆盖其他测试参数。
pytest 9.0.1 会在检测到 iTerm2 后自动关闭此功能。检测依赖 ITERM_SESSION_ID;tox 默认不会透传所有宿主环境变量,容器内也未必有它。结果是宿主终端虽然是 iTerm2,测试进程却不知道,仍发送控制序列。此时,显式加 -p no:terminalprogress 比依赖检测更直接,也适用于 CI 的测试命令。
pytest 9.0.2 从默认行为上进一步调整:除 Windows 外,默认关闭 terminalprogress。Windows 的默认行为和显式启用 -p terminalprogress 的配置要分别检查,不能把这项改变概括成“所有平台都关闭了”。iTerm2 3.6.6 已增加对进度序列的支持;如果确实需要终端窗口上的进度显示,可以在升级终端后单独验证,再决定是否启用。
验证时用原来会触发通知的测试入口运行同一小组测试,确认通知停止、测试数和退出码没有改变。如果直接运行已正常,tox 或 Docker 仍异常,就检查包装命令实际传入的参数及配置文件。不要只在宿主机执行 pytest --version,然后假定容器内也是同一版本。
若禁用 terminalprogress 后通知照样出现,说明还存在其他通知来源,应继续查测试调用的程序和终端设置。这条办法只处理 pytest 发出的额外进度控制序列,不会阻止应用程序主动发送的系统通知。


