有时候,我只想在代码中插入一些打印语句,然后看看在执行该操作时打印出来的内容。我通常的“锻炼”方式是使用现有的pytest测试。但是,当我运行这些命令时,我似乎看不到任何标准输出(至少从我的IDE PyCharm内部)。
有没有一种简单的方法可以在pytest运行期间查看标准输出?
有时候,我只想在代码中插入一些打印语句,然后看看在执行该操作时打印出来的内容。我通常的“锻炼”方式是使用现有的pytest测试。但是,当我运行这些命令时,我似乎看不到任何标准输出(至少从我的IDE PyCharm内部)。
有没有一种简单的方法可以在pytest运行期间查看标准输出?
Answers:
该-s
开关禁用每次测试捕获。
-s
=--capture=no
有什么方法可以打印到控制台并捕获输出,以便将其显示在junit报告中?
在UNIX中,这通常称为teeing。理想情况下,py.test默认是发球而不是捕获。尽管Python很少支持开箱即用,但py.test或任何现有的第三方py.test插件(无论如何我都知道)都不理想。
用猴子修补py.test来做不受支持的事情并非易事。为什么?因为:
_pytest
软件包后面。尝试这样做而不知道自己在做什么,通常会导致公共包在运行时引发模糊的异常。非常感谢py.test。真正可靠的体系结构。pytest
_pytest
安全的方式对专用API 进行猴子补丁的操作,也必须在运行pytest
由外部py.test
命令运行的公共程序包之前这样做。您不能在插件中执行此操作(例如,conftest
测试套件中的顶级模块)。到py.test懒惰地动态导入插件时,您想要进行猴子补丁的任何py.test类都已被实例化很久了-并且您无权访问该实例。这意味着,如果您希望有意义地应用猴子补丁,则无法再安全地运行外部py.test
命令。相反,您必须使用自定义setuptools包装该命令的运行test
命令(按顺序):
_pytest
API。pytest.main()
函数运行py.test
命令。这个答案是猴子修补py.test -s
和--capture=no
选项来捕获stderr而不是 stdout的。默认情况下,这些选项既不捕获stderr也不捕获stdout。当然,这还不够。但是,每一次伟大的旅程都是从一个繁琐的前传开始的,每个人在五年之内就忘记了。
为什么这样 我现在告诉你。我的py.test驱动的测试套件包含缓慢的功能测试。显示这些测试的标准输出是有益的,让人放心,防止leycec到达了killall -9 py.test
当又一个长期运行的功能测试失败做几星期什么。但是,显示这些测试的stderr可以防止py.test报告有关测试失败的异常回溯。这是完全没有帮助的。因此,我们强制py.test捕获stderr 而不捕获stdout。
在开始之前,此答案假定您已经有一个test
调用py.test 的自定义setuptools 命令。如果不这样做,请参阅py.test编写良好的“良好做法”页面的“ 手动集成”小节。
不要不安装pytest亚军,第三方插件setuptools的提供自定义setuptools的test
命令也调用py.test。如果已经安装pytest-runner,则可能需要卸载该pip3软件包,然后采用上面链接的手动方法。
假设您按照上面突出显示的“ 手动集成”中的说明进行操作,则您的代码库现在应包含一个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)
要启用此猴子补丁,请运行py.test,如下所示:
python setup.py test -a "-s"
现在将捕获Stderr而不是 stdout。好漂亮!
将上面的猴子补丁扩展到tee stdout和stderr上,作为练习,留给读者一整桶的空闲时间。
pytest捕获单个测试的标准输出,并仅在特定条件下显示它们,并默认显示其打印的测试摘要。
额外的摘要信息可以使用'-r'选项显示:
pytest -rP
显示已通过测试的捕获输出。
pytest -rx
显示捕获的失败测试输出(默认行为)。
-r的输出格式比-s的输出格式更漂亮。
尝试 pytest -s -v test_login.py
在控制台中获取更多信息。
-v
很短 --verbose
-s
表示“禁用所有捕获”