Python 如何在pytest中打印到控制台?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24617397/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:53:24  来源:igfitidea点击:

How to print to console in pytest?

pythonunit-testingpython-2.7pytest

提问by BBedit

I'm trying to use TDD (test-driven development) with pytest. pytestwill not printto the console when I use print.

我正在尝试将 TDD(测试驱动开发)与pytest. pytest不会print当我使用控制台print

I am using pytest my_tests.pyto run it.

我正在使用pytest my_tests.py它来运行它。

The documentationseems to say that it should work by default: http://pytest.org/latest/capture.html

documentation似乎是说,它应该是默认的工作:http://pytest.org/latest/capture.html

But:

但:

import myapplication as tum

class TestBlogger:

    @classmethod
    def setup_class(self):
        self.user = "alice"
        self.b = tum.Blogger(self.user)
        print "This should be printed, but it won't be!"

    def test_inherit(self):
        assert issubclass(tum.Blogger, tum.Site)
        links = self.b.get_links(posts)
        print len(links)   # This won't print either.

Nothing gets printed to my standard output console (just the normal progress and how many many tests passed/failed).

没有任何内容打印到我的标准输出控制台(只是正常进度以及通过/失败的测试数量)。

And the script that I'm testing contains print:

我正在测试的脚本包含打印:

class Blogger(Site):
    get_links(self, posts):
        print len(posts)   # It won't get printed in the test.

In unittestmodule, everything gets printed by default, which is exactly what I need. However, I wish to use pytestfor other reasons.

unittest模块中,默认情况下会打印所有内容,这正是我所需要的。但是,我希望pytest出于其他原因使用。

Does anyone know how to make the print statements get shown?

有谁知道如何显示打印语句?

采纳答案by tbekolay

By default, py.testcaptures the result of standard out so that it can control how it prints it out. If it didn't do this, it would spew out a lot of text without the context of what test printed that text.

默认情况下,py.test捕获标准输出的结果,以便它可以控制它的打印方式。如果它不这样做,它会在没有测试打印文本的上下文的情况下喷出大量文本。

However, if a test fails, it will include a section in the resulting report that shows what was printed to standard out in that particular test.

但是,如果测试失败,它将在结果报告中包含一个部分,显示在该特定测试中打印的标准输出内容。

For example,

例如,

def test_good():
    for i in range(1000):
        print(i)

def test_bad():
    print('this should fail!')
    assert False

Results in the following output:

结果如下:

>>> py.test tmp.py
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py .F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
------------------------------- Captured stdout --------------------------------
this should fail!
====================== 1 failed, 1 passed in 0.04 seconds ======================

Note the Captured stdoutsection.

请注意该Captured stdout部分。

If you would like to see printstatements as they are executed, you can pass the -sflag to py.test. However, note that this can sometimes be difficult to parse.

如果您想print在执行时查看语句,可以将-s标志传递给py.test. 但是,请注意,这有时可能难以解析。

>>> py.test tmp.py -s
============================= test session starts ==============================
platform darwin -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
plugins: cache, cov, pep8, xdist
collected 2 items

tmp.py 0
1
2
3
... and so on ...
997
998
999
.this should fail!
F

=================================== FAILURES ===================================
___________________________________ test_bad ___________________________________

    def test_bad():
        print('this should fail!')
>       assert False
E       assert False

tmp.py:7: AssertionError
====================== 1 failed, 1 passed in 0.02 seconds ======================

回答by dmitry_romanov

Using -soption will print output of all functions, which may be too much.

使用-soption 将打印所有函数的输出,这可能太多了。

If you need particular output, the doc page you mentioned offers few suggestions:

如果您需要特定的输出,您提到的文档页面提供了一些建议:

  1. Insert assert False, "dumb assert to make PyTest print my stuff"at the end of your function, and you will see your output due to failed test.

  2. You have special object passed to you by PyTest, and you can write the output into a file to inspect it later, like

    def test_good1(capsys):
        for i in range(5):
            print i
        out, err = capsys.readouterr()
        open("err.txt", "w").write(err)
        open("out.txt", "w").write(out)
    

    You can open the outand errfiles in a separate tab and let editor automatically refresh it for you, or do a simple py.test; cat out.txtshell command to run your test.

  1. assert False, "dumb assert to make PyTest print my stuff"在函数的末尾插入,由于测试失败,您将看到输出。

  2. 您有 PyTest 传递给您的特殊对象,您可以将输出写入文件以供稍后检查,例如

    def test_good1(capsys):
        for i in range(5):
            print i
        out, err = capsys.readouterr()
        open("err.txt", "w").write(err)
        open("out.txt", "w").write(out)
    

    您可以在单独的选项卡中打开outerr文件,让编辑器自动为您刷新,或者执行简单的py.test; cat out.txtshell 命令来运行您的测试。

That is rather hackish way to do stuff, but may be it is the stuff you need: after all, TDD means you mess with stuff and leave it clean and silent when it's ready :-).

这是一种相当骇人听闻的做事方式,但可能正是您需要的东西:毕竟,TDD 意味着您将东西弄得一团糟,并在它准备好时让它保持干净和安静:-)。

回答by dmitry_romanov

I needed to print important warning about skipped tests exactly when PyTestmuted literally everything.

我需要准确地打印关于跳过测试的重要警告,而PyTest实际上一切都被静音了。

I didn't want to fail a test to send a signal, so I did a hack as follow:

我不想在发送信号的测试中失败,所以我做了如下黑客攻击:

def test_2_YellAboutBrokenAndMutedTests():
    import atexit
    def report():
        print C_patch.tidy_text("""
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.""")
    if sys.stdout != sys.__stdout__:
        atexit.register(report)

The atexitmodule allows me to print stuff afterPyTestreleased the output streams. The output looks as follow:

atexit模块允许我PyTest发布输出流打印内容。输出如下所示:

============================= test session starts ==============================
platform linux2 -- Python 2.7.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /media/Storage/henaro/smyth/Alchemist2-git/sources/C_patch, inifile: 
collected 15 items 

test_C_patch.py .....ssss....s.

===================== 10 passed, 5 skipped in 0.15 seconds =====================
In silent mode PyTest breaks low level stream structure I work with, so
I cannot test if my functionality work fine. I skipped corresponding tests.
Run `py.test -s` to make sure everything is tested.
~/.../sources/C_patch$

Message is printed even when PyTestis in silent mode, and is notprinted if you run stuff with py.test -s, so everything is tested nicely already.

即使PyTest在静默模式下也会打印消息,并且如果您使用 运行东西则不会打印py.test -s,因此所有内容都已经过很好的测试。

回答by Karthik Gomadam Rajagopal

According to the pytest docs, pytest --capture=sysshould work. If you want to capture standard out inside a test, refer to the capsys fixture.

根据pytest docspytest --capture=sys应该可以工作。如果您想在测试中捕获标准输出,请参阅 capsys 夹具。

回答by lmiguelvargasf

Short Answer

简答

Use the -soption:

使用-s选项:

pytest -s

Detailed answer

详细解答

From the docs:

文档

During test execution any output sent to stdoutand stderris captured. If a test or a setup method fails its according captured output will usually be shown along with the failure traceback.

在测试执行期间,任何发送到stdoutstderr 的输出都会被捕获。如果测试或设置方法失败,其相应的捕获输出通常会与失败回溯一起显示。

pytesthas the option --capture=methodin which methodis per-test capturing method, and could be one of the following: fd, sysor no. pytestalso has the option -swhich is a shortcut for --capture=no, and this is the option that will allow you to see your print statements in the console.

pytest有一个选项--capture=method,其中method是 per-test 捕获方法,并且可以是以下之一:fd,sysnopytest还有一个选项-s,它是 的快捷方式--capture=no,这是允许您在控制台中查看打印语句的选项。

pytest --capture=no     # show print statements in console
pytest -s               # equivalent to previous command

Setting capturing methods or disabling capturing

设置捕获方法或禁用捕获

There are two ways in which pytestcan perform capturing:

有两种方法pytest可以执行捕获:

  1. file descriptor (FD) level capturing(default): All writes going to the operating system file descriptors 1 and 2 will be captured.

  2. sys level capturing: Only writes to Python files sys.stdout and sys.stderr will be captured. No capturing of writes to filedescriptors is performed.

  1. 文件描述符 (FD) 级别捕获(默认):将捕获所有写入操作系统文件描述符 1 和 2 的内容。

  2. sys level capture:只会捕获写入 Python 文件 sys.stdout 和 sys.stderr 的内容。不执行对文件描述符的写入的捕获。

pytest -s            # disable all capturing
pytest --capture=sys # replace sys.stdout/stderr with in-mem files
pytest --capture=fd  # also point filedescriptors 1 and 2 to temp file

回答by dummyDev

I originally came in here to find how to make PyTestprint in VSCode's console while running/debugging the unit test from there. This can be done with the following launch.jsonconfiguration. Given .venvthe virtual environment folder.

我最初来到这里是为了找到如何PyTest在 VSCode 的控制台中进行打印,同时从那里运行/调试单元测试。这可以通过以下launch.json配置来完成。给定.venv虚拟环境文件夹。

    "version": "0.2.0",
    "configurations": [
        {
            "name": "PyTest",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "pythonPath": "${config:python.pythonPath}",
            "module": "pytest",
            "args": [
                "-sv"
            ],
            "cwd": "${workspaceRoot}",
            "env": {},
            "envFile": "${workspaceRoot}/.venv",
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit",
                "RedirectOutput"
            ]
        }
    ]
}