Python 如何查看在 pytest 运行期间创建的正常打印输出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14405063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I see normal print output created during pytest run?
提问by Des
Sometimes I want to just insert some print statements in my code, and see what gets printed out when I exercise it. My usual way to "exercise" it is with existing pytest tests. But when I run these, I don't seem able to see any standard output (at least from within PyCharm, my IDE).
有时我只想在我的代码中插入一些打印语句,然后看看当我执行它时会打印出什么。我通常“锻炼”它的方法是使用现有的 pytest 测试。但是当我运行这些时,我似乎看不到任何标准输出(至少在我的 IDE PyCharm 中)。
Is there a simple way to see standard output during a pytest run?
有没有一种简单的方法可以在 pytest 运行期间查看标准输出?
回答by Summerfun
When running the test use the -soption. All print statements in exampletest.pywould get printed on the console when test is run.
运行测试时使用该-s选项。exampletest.py运行测试时,所有打印语句都将打印在控制台上。
py.test exampletest.py -s
回答by Cecil Curry
In an upvoted commentto the accepted answer, Joeasks:
Is there any way to print to the console ANDcapture the output so that it shows in the junit report?
有什么方法可以打印到控制台并捕获输出,以便它显示在 junit 报告中?
In UNIX, this is commonly referred to as teeing. Ideally, teeing rather than capturing would be the py.test default. Non-ideally, neither py.test nor any existing third-party py.test plugin (...that I know of, anyway) supports teeing – despite Python trivially supporting teeing out-of-the-box.
在 UNIX 中,这通常称为teeing。理想情况下,开球而不是捕获将是 py.test 的默认设置。非理想情况下,无论是 py.test 还是任何现有的第三方 py.test 插件(...我都知道,反正)支持开球——尽管 Python 微不足道地支持开箱即用的开球。
Monkey-patching py.test to do anythingunsupported is non-trivial. Why? Because:
Monkey-patching py.test 做任何不受支持的事情是很重要的。为什么?因为:
- Most py.test functionality is locked behind a private
_pytestpackage notintended to be externally imported. Attempting to do so without knowing what you're doing typically results in the publicpytestpackage raising obscure exceptions at runtime. Thanks alot, py.test. Really robust architecture you got there. - Even when you dofigure out how to monkey-patch the private
_pytestAPI in a safe manner, you have to do so beforerunning the publicpytestpackage run by the externalpy.testcommand. You cannotdo this in a plugin (e.g., a top-levelconftestmodule in your test suite). By the time py.test lazily gets around to dynamically importing your plugin, any py.test class you wanted to monkey-patch has long since been instantiated – and you do nothave access to that instance. This implies that, if you want your monkey-patch to be meaningfully applied, you can no longer safely run the externalpy.testcommand. Instead, you have to wrap the running of that command with a custom setuptoolstestcommand that (in order):- Monkey-patches the private
_pytestAPI. - Calls the public
pytest.main()function to run thepy.testcommand.
- Monkey-patches the private
- 大多数 py.test 功能被锁定在一个不打算从外部导入的私有
_pytest包后面。在不知道您在做什么的情况下尝试这样做通常会导致公共包在运行时引发模糊的异常。非常感谢,py.test。你到了那里,真正强大的架构。pytest - 即使您确实想出了如何以
_pytest安全的方式修补私有API,您也必须在运行pytest由外部py.test命令运行的公共包之前这样做。您不能在插件(例如,conftest测试套件中的顶级模块)中执行此操作。当 py.test 懒洋洋地开始动态导入您的插件时,您想要进行猴子补丁的任何 py.test 类早已被实例化——而您无权访问该实例。这意味着,如果您想要有意义地应用您的猴子补丁,您将无法再安全地运行外部py.test命令。相反,您必须使用自定义 setuptools 包装该命令的运行test命令(按顺序):- Monkey 修补了私有
_pytestAPI。 - 调用公共
pytest.main()函数来运行py.test命令。
- Monkey 修补了私有
This answer monkey-patches py.test's -sand --capture=nooptions to capture stderr but notstdout. By default, these options capture neither stderr nor stdout. This isn't quite teeing, of course. But every great journey begins with a tedious prequel everyone forgets in five years.
这个答案猴子补丁 py.test's-s和--capture=no选项来捕获 stderr 但不是stdout。默认情况下,这些选项既不捕获 stderr 也不捕获 stdout。当然,这并不完全是开球。但每一次伟大的旅程都始于乏味的前传,每个人都会在五年内忘记。
Why do this? I shall now tell you. My py.test-driven test suite contains slow functional tests. Displaying the stdout of these tests is helpful and reassuring, preventing leycecfrom reaching for killall -9 py.testwhen yet another long-running functional test fails to do anything for weeks on end. Displaying the stderr of these tests, however, prevents py.test from reporting exception tracebacks on test failures. Which is completely unhelpful. Hence, we coerce py.test to capture stderr but notstdout.
为什么要这样做?我现在告诉你。我的 py.test 驱动的测试套件包含缓慢的功能测试。显示这些测试的标准输出是有帮助的和令人放心的,当另一个长期运行的功能测试连续数周未能做任何事情时,可以防止leycec伸手去拿killall -9 py.test。但是,显示这些测试的 stderr 会阻止 py.test 报告测试失败时的异常回溯。这是完全没有帮助的。因此,我们强制 py.test 捕获 stderr 而不是stdout。
Before we get to it, this answer assumes you already have a custom setuptools testcommand invoking py.test. If you don't, see the Manual Integrationsubsection of py.test's well-written Good Practicespage.
在我们开始之前,这个答案假设您已经有一个test调用 py.test的自定义 setuptools命令。如果没有,请参阅py.test 编写良好的良好实践页面的手动集成小节。
Do notinstall pytest-runner, a third-party setuptools plugin providing a custom setuptools testcommand also invoking py.test. If pytest-runner is already installed, you'll probably need to uninstall that pip3 package and then adopt the manual approach linked to above.
不要不安装pytest亚军,第三方插件setuptools的提供自定义setuptools的test命令也调用py.test。如果 pytest-runner 已经安装,你可能需要卸载那个 pip3 包,然后采用上面链接的手动方法。
Assuming you followed the instructions in Manual Integrationhighlighted above, your codebase should now contain a PyTest.run_tests()method. Modify this method to resemble:
假设您按照上面突出显示的手动集成中的说明进行操作,您的代码库现在应该包含一个PyTest.run_tests()方法。修改此方法以类似于:
class PyTest(TestCommand):
.
.
.
def run_tests(self):
# Import the public "pytest" package *BEFORE* the private "_pytest"
# package. While importation order is typically ignorable, imports can
# technically have side effects. Tragicomically, that is the case here.
# Importing the public "pytest" package establishes runtime
# configuration required by submodules of the private "_pytest" package.
# The former *MUST* always be imported before the latter. Failing to do
# so raises obtuse exceptions at runtime... which is bad.
import pytest
from _pytest.capture import CaptureManager, FDCapture, MultiCapture
# If the private method to be monkey-patched no longer exists, py.test
# is either broken or unsupported. In either case, raise an exception.
if not hasattr(CaptureManager, '_getcapture'):
from distutils.errors import DistutilsClassError
raise DistutilsClassError(
'Class "pytest.capture.CaptureManager" method _getcapture() '
'not found. The current version of py.test is either '
'broken (unlikely) or unsupported (likely).'
)
# Old method to be monkey-patched.
_getcapture_old = CaptureManager._getcapture
# New method applying this monkey-patch. Note the use of:
#
# * "out=False", *NOT* capturing stdout.
# * "err=True", capturing stderr.
def _getcapture_new(self, method):
if method == "no":
return MultiCapture(
out=False, err=True, in_=False, Capture=FDCapture)
else:
return _getcapture_old(self, method)
# Replace the old with the new method.
CaptureManager._getcapture = _getcapture_new
# Run py.test with all passed arguments.
errno = pytest.main(self.pytest_args)
sys.exit(errno)
To enable this monkey-patch, run py.test as follows:
要启用此猴子补丁,请按如下方式运行 py.test:
python setup.py test -a "-s"
Stderr but notstdout will now be captured. Nifty!
现在将捕获Stderr 而不是stdout。漂亮!
Extending the above monkey-patch to tee stdout and stderr is left as an exercise to the reader with a barrel-full of free time.
将上面的monkey-patch 扩展到tee stdout 和stderr 作为练习留给读者,并有充足的空闲时间。
回答by Roman Susi
According to pytest documentation, version 3 of pytest can temporary disable capture in a test:
根据pytest 文档,pytest 的第 3 版可以在测试中临时禁用捕获:
def test_disabling_capturing(capsys):
print('this output is captured')
with capsys.disabled():
print('output not captured, going directly to sys.stdout')
print('this output is also captured')
回答by Alex Makarenko
Try pytest -s -v test_login.pyfor more info in console.
尝试 pytest -s -v test_login.py在控制台中获取更多信息。
-vit's a short --verbose
-v这是一个简短的 --verbose
-smeans 'disable all capturing'
-s意思是“禁用所有捕获”
回答by Gemini Jain
If you are using PyCharm IDE, then you can run that individual test or all tests using Run toolbar. The Run tool window displays output generated by your application and you can see all the print statements in there as part of test output.
如果您使用的是 PyCharm IDE,那么您可以使用运行工具栏运行该单个测试或所有测试。“运行”工具窗口显示应用程序生成的输出,您可以在其中查看作为测试输出一部分的所有打印语句。
回答by aaa90210
The other answers don't work. The onlyway to see the captured output is using the following flag:
其他答案不起作用。查看捕获的输出的唯一方法是使用以下标志:
pytest --show-capture all
pytest --show-capture 全部
回答by Sunthar
pytest captures the stdout from individual tests and displays them only on certain conditions, along with the summary of the tests it prints by default.
pytest 从单个测试中捕获标准输出,并仅在特定条件下显示它们,以及它默认打印的测试摘要。
Extra summary infocan be shown using the '-r' option:
可以使用“-r”选项显示额外的摘要信息:
pytest -rP
shows the captured output of passed tests.
显示通过测试的捕获输出。
pytest -rx
shows the captured output of failed tests (default behaviour).
显示失败测试的捕获输出(默认行为)。
The formatting of the output is prettier with -r than with -s.
-r 的输出格式比 -s 更漂亮。
回答by meonstackexchange
pytest --capture=tee-syswas recently added. You can capture as well as see the output on stdout/err.
pytest --capture=tee-sys最近添加的。您可以捕获以及查看 stdout/err 上的输出。

