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

Des*_*Des 320 python logging pytest output

有时我想在我的代码中插入一些打印语句,看看在我练习时会打印出来的内容.我通常的"锻炼"方法是使用现有的pytest测试.但是当我运行这些时,我似乎无法看到任何标准输出(至少来自PyCharm,我的IDE).

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

hpk*_*k42 454

-s开关禁用每次测试捕获.

  • `-s` =`--capture = no` (65认同)
  • 这会导致输出与 Pytest 输出交错。您可能希望 Pytest 像往常一样捕获输出,并在测试通过和失败时显示它。请参阅/sf/answers/4140969521/ (9认同)
  • 如何在*运行期间*看到打印结果而不等待结束? (7认同)
  • 这不起作用,任何 --capture 选项也不起作用。唯一有效的选项是“-o log_cli=True”。但是,-s 的含义自 2013 年以来完全有可能发生变化。 (4认同)
  • 如果使用日志记录,另请参阅 /sf/ask/327136141/ 了解与“-s”一起使用的其他选项 (2认同)

小智 135

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

可以使用“-r”选项显示额外的摘要信息

pytest -rP
Run Code Online (Sandbox Code Playgroud)

显示通过测试的捕获输出。

pytest -rx
Run Code Online (Sandbox Code Playgroud)

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

-r 的输出格式比 -s 更漂亮。

  • pytest -rA 应该打印所有输出。https://docs.pytest.org/en/6.2.x/reference.html?highlight=command%20line#command-line-flags (20认同)
  • 这就是我一直在寻找的实际答案!谢谢。(希望标准输出在测试结果**之后**出现。当它们交错时,打印的行会失去价值。) (18认同)
  • 如何在 Pycharm 中执行此操作(不通过命令行)? (2认同)
  • 请注意@rsmith54 评论是最好的评论。特别是如果您正在进行大量测试,并且每次都想查看该特定测试的失败或通过输出,那么“-rA”就可以做到。这是最简单的一刀切的答案。 (2认同)

Cec*_*rry 48

接受回答的评论中,问道:

有没有办法打印到控制台捕获输出,以便它显示在junit报告中?

在UNIX中,这通常被称为teeing.理想情况下,teeing而不是捕获将是py.test默认值.非理想情况下,py.test和任何现有的第三方py.test插件(我知道,无论如何)都不支持发球 - 尽管Python平凡地支持开箱即用的发球.

猴子修补py.test做任何不受支持的事情都是非平凡的.为什么?因为:

  • 大多数py.test功能都锁定在打算从外部导入的私有_pytest包之后.试图在不知道你正在做什么的情况下这样做通常会导致公共包在运行时引发模糊的异常.非常感谢,py.test.你到那里真的很健壮的建筑.pytest
  • 即使你弄清楚如何猴子修补私人_pytest安全地API,你必须这样做之前运行的公共pytest包由外部运行py.test命令.您不能在插件中执行此操作(例如,conftest测试套件中的顶级模块).当py.test懒惰地动态导入你的插件时,你想要实现猴子补丁的任何py.test类早已被实例化 - 并且你无权访问该实例.这意味着,如果您希望有意义地应用您的monkey-patch,则无法再安全地运行外部py.test命令.相反,您必须使用自定义setuptools test命令(按顺序)包装该命令的运行:
    1. Monkey-patches私有_pytestAPI.
    2. 调用public pytest.main()函数来运行py.test命令.

这个答案猴子补丁py.test -s--capture=no捕获stderr但不是 stdout的选项.默认情况下,这些选项既不捕获stderr也不捕获stdout.当然,这不是很发球.但是每一个伟大的旅程都始于一个繁琐的前传,每个人都会忘记五年.

为什么这样?我现在要告诉你.我的py.test驱动的测试套件包含慢速功能测试.显示这些测试的标准输出是有帮助的,可以让人放心,防止leyceckillall -9 py.test在另一个长期运行的功能测试未能连续几周做任何事情时触及.但是,显示这些测试的stderr会阻止py.test报告测试失败时的异常回溯.这完全没有用.因此,我们强制py.test捕获stderr而不是 stdout.

在我们开始之前,这个答案假设您已经有一个自定义setuptools test命令来调用py.test.如果不这样做,请参阅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)
Run Code Online (Sandbox Code Playgroud)

要启用此monkey-patch,请运行py.test,如下所示:

python setup.py test -a "-s"
Run Code Online (Sandbox Code Playgroud)

现在将捕获Stderr而不是 stdout.漂亮!

将上面的猴子补丁扩展到tee stdout和stderr,留给玩家一个充满空闲时间的练习.

  • pytest 与 `--capture=tee-sys` 一起使用 https://docs.pytest.org/en/stable/capture.html#setting-capturing-methods-or-disabling-capturing (2认同)

小智 25

运行测试时使用该-s选项.exampletest.py运行测试时,所有打印语句都将打印在控制台上.

py.test exampletest.py -s
Run Code Online (Sandbox Code Playgroud)


Rom*_*usi 25

根据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')
Run Code Online (Sandbox Code Playgroud)


meo*_*nge 18

pytest --capture=tee-sys最近添加(v5.4.0)。您可以捕获以及查看 stdout/err 上的输出。


Ale*_*nko 13


pytest -s -v test_login.py在控制台中尝试 更多信息.

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

-s 意味着'禁用所有捕获'



  • 如果您使用 pytest.ini 文件,您可以使用: addopts = -s -v python_files = test_login.py (3认同)

Kir*_* Sk 11

pytest test_name.py -v -s
Run Code Online (Sandbox Code Playgroud)

简单的!


dvv*_*vrt 7

您还可以通过在项目根目录中或中设置以下内容来启用 实时日志记录pytest.initox.ini

[pytest]
log_cli = True
Run Code Online (Sandbox Code Playgroud)

或者直接在cli上指定

pytest -o log_cli=True
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用下面的这些命令显示打印输出。*-rP可以比-s,--capture=no和更清晰地显示打印输出--capture=tee-sys

pytest -rP
Run Code Online (Sandbox Code Playgroud)
pytest -s
Run Code Online (Sandbox Code Playgroud)
pytest --capture=no
Run Code Online (Sandbox Code Playgroud)
pytest --capture=tee-sys
Run Code Online (Sandbox Code Playgroud)


Vov*_*ova 5

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

pytest <test_file.py> -s
Run Code Online (Sandbox Code Playgroud)


sag*_*age 5

如果您使用的是logging,除了通用 stdout 之外,您还需要指定打开日志输出-s。基于pytest 测试中的日志记录,我正在使用:

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