Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何查看在pytest运行期间创建的正常打印输出?_Python_Logging_Output_Pytest - Fatal编程技术网

Python 如何查看在pytest运行期间创建的正常打印输出?

Python 如何查看在pytest运行期间创建的正常打印输出?,python,logging,output,pytest,Python,Logging,Output,Pytest,有时,我只想在代码中插入一些print语句,看看在执行时会打印出什么。我通常使用现有的pytest测试来“锻炼”它。但当我运行这些时,我似乎看不到任何标准输出(至少在我的IDE PyCharm中) 有没有一种简单的方法可以在pytest运行期间查看标准输出?禁用每次测试捕获(仅当测试失败时)。运行测试时,请使用-s选项。当测试运行时,exampletest.py中的所有打印语句都会在控制台上打印出来 py.test exampletest.py -s 在对的答复中,询问: 是否有任何方法可以打

有时,我只想在代码中插入一些print语句,看看在执行时会打印出什么。我通常使用现有的pytest测试来“锻炼”它。但当我运行这些时,我似乎看不到任何标准输出(至少在我的IDE PyCharm中)


有没有一种简单的方法可以在pytest运行期间查看标准输出?

禁用每次测试捕获(仅当测试失败时)。

运行测试时,请使用
-s
选项。当测试运行时,
exampletest.py
中的所有打印语句都会在控制台上打印出来

py.test exampletest.py -s
在对的答复中,询问:

是否有任何方法可以打印到控制台并捕获输出,以便它显示在junit报告中

在UNIX中,这通常称为。理想情况下,py.test默认设置是T型而不是捕获。在非理想情况下,py.test和任何现有的第三方py.test插件(……无论如何,我知道)都不支持T形三通——尽管Python支持T形三通

Monkey patching py.test做任何不受支持的事情是非常重要的。为什么?因为:

  • 大多数py.test功能被锁定在一个私有的
    \u pytest
    包后面,不打算从外部导入。在不知道自己在做什么的情况下尝试这样做通常会导致public
    pytest
    包在运行时引发模糊的异常。非常感谢你,佩妮。你的架构真的很强大
  • 即使您确实知道如何以安全的方式对私有
    \u pytest
    API进行猴子补丁,您也必须在运行由外部
    py.test
    命令运行的公共
    pytest
    包之前进行此操作。您不能在插件中执行此操作(例如,测试套件中的顶级
    conftest
    模块)。当py.test懒洋洋地开始动态导入你的插件时,你想要蒙骗补丁的任何py.test类早就被实例化了——你没有访问该实例的权限。这意味着,如果您希望有意义地应用monkey补丁,则无法再安全地运行external
    py.test
    命令。相反,您必须使用自定义的setuptools
    test
    命令来包装该命令的运行(顺序):
  • Monkey修补了私有的
    \u pytest
    API
  • 调用public
    pytest.main()
    函数来运行
    py.test
    命令
这个答案使用py.test的
-s
-capture=no
选项来捕获stderr而不是stdout。默认情况下,这些选项既不捕获stderr也不捕获stdout。当然,这不是很好的发球。但每一次伟大的旅程都是从一部乏味的前传开始的,每个人都会在五年内忘记这部前传

为什么要这样做?我现在告诉你。我的py.test驱动测试套件包含缓慢的功能测试。显示这些测试的标准是有帮助和令人放心的,可以防止当另一个长时间运行的功能测试连续数周都没有做任何事情时,达到
killall-9 py.test
。但是,显示这些测试的stderr可以防止py.test报告测试失败时的异常回溯。这是完全没有帮助的。因此,我们强制py.test捕获stderr而不是stdout

在开始之前,这个答案假设您已经有一个调用py.test的自定义setuptools
test
命令。如果没有,请参阅py.test编写良好的页面的小节

不安装,第三方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)
要启用此monkey修补程序,请按如下方式运行py.test:

python setup.py test -a "-s"
现在将捕获Stderr而不是stdout。漂亮

将上述猴子补丁扩展到tee stdout和stderr是留给读者的一个练习,读者有充足的空闲时间。

根据,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')

请尝试使用pytest-s-v test\u login.py查看控制台中的更多信息

-v
这是一个简短的
--verbose

-s
表示“禁用所有捕获”




如果您使用的是PyCharm IDE,那么您可以使用运行工具栏运行单个测试或所有测试。运行工具窗口显示应用程序生成的输出,您可以在其中看到作为测试输出一部分的所有打印语句。

pytest从各个测试捕获标准输出,并仅在特定条件下显示它们,以及默认情况下打印的测试摘要

可以使用“-r”选项显示:

pytest -rP
显示已通过测试的捕获输出

pytest -rx
显示失败测试的捕获输出(默认行为)

使用-r时输出的格式比使用-s时更美观。

pytest--capture=tee sys
最近添加了()。您可以在stdout/err上捕获并查看输出。

您还可以通过在项目根目录中的
pytest.ini
tox.ini
中设置以下内容来启用

[pytest]
log_cli = True
或者直接在cli上指定它

pytest -o log_cli=True

简单

我建议使用-h命令。可能会使用一些非常有趣的命令。 但是,对于这种特殊情况:-s的快捷方式--capture=no.就足够了

pytest <test_file.py> -s
pytest-s

如果您使用的是
日志记录
,则除了通用标准输出的
-s
之外,还需要指定打开日志记录输出。基于,我正在使用:

pytest--log cli level=DEBUG-s my_directory/

仅在出现故障或alwa时
pytest <test_file.py> -s