pytest默认捕获print输出,仅失败时显示;加-s参数关闭捕获实现实时打印,-s不可写作--s,可与-v合并为-vs,但可能被pytest.ini等配置覆盖。

因为 pytest 默认会捕获 print() 输出,不加 -s 就看不到任何 print 内容。
pytest 默认捕获 stdout 是为了结构化报告
pytest 设计上把测试运行当成一个“受控过程”:它拦截 sys.stdout 和 sys.stderr,把所有 print()、logging.info() 等输出暂存起来。只有测试失败时,才把捕获的内容附在 traceback 后面一并显示;成功时则完全丢弃。这是为了防止调试信息污染结果统计(比如 100 个点全绿,但中间刷了一屏 print 很难定位 PASS/FAIL)。
所以你写:
def test_example():
print("debug: a = 1")
assert 1 == 2
不加 -s 时,只看到断言失败的 traceback,那行 print 消失了;加了 -s 才会在终端实时刷出 debug: a = 1。
立即学习“Python免费学习笔记(深入)”;
-s 的实际行为和常见误用
-
-s不是“开启打印”,而是“关闭捕获”——它让print()直接流向终端,和普通脚本行为一致 - 参数名是
-s,不是--s或--print,写成--s会被忽略 -
-s和-v可以合并写成-vs,顺序无关,pytest -v -s test.py和pytest -s -v test.py效果一样 - 如果加了
-s还看不到输出,大概率是项目里存在pytest.ini或pyproject.toml覆盖了命令行参数(比如配置里漏写了-s)
什么时候必须用 -s,什么时候可以不用
必须用 -s 的场景:
- 调试时想看中间变量值:
print(f"response.status_code = {r.status_code}") - 测试中调用了含
input()的逻辑(否则会卡住) - 验证日志是否按预期输出(配合
caplogfixture 除外)
可以不用的场景:
- CI 流水线跑回归测试——不需要人工盯输出,失败时 pytest 自动把捕获内容贴在错误堆栈后
- 用
capsysfixture 做断言:assert "expected" in capsys.readouterr().out,此时-s反而干扰判断
真正容易被忽略的是配置文件的覆盖行为:哪怕你敲了 pytest -s,只要根目录有 pytest.ini 且没显式包含 -s,它就失效。最稳的做法是在配置里固定写死 addopts = -v -s,而不是每次靠记参数。



















