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
How to print to console in pytest?
提问by BBedit
I'm trying to use TDD (test-driven development) with pytest
.
pytest
will not print
to the console when I use print
.
我正在尝试将 TDD(测试驱动开发)与pytest
.
pytest
不会print
当我使用控制台print
。
I am using pytest my_tests.py
to run it.
我正在使用pytest my_tests.py
它来运行它。
The documentation
seems 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 unittest
module, everything gets printed by default, which is exactly what I need. However, I wish to use pytest
for other reasons.
在unittest
模块中,默认情况下会打印所有内容,这正是我所需要的。但是,我希望pytest
出于其他原因使用。
Does anyone know how to make the print statements get shown?
有谁知道如何显示打印语句?
采纳答案by tbekolay
By default, py.test
captures 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 stdout
section.
请注意该Captured stdout
部分。
If you would like to see print
statements as they are executed, you can pass the -s
flag 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 -s
option will print output of all functions, which may be too much.
使用-s
option 将打印所有函数的输出,这可能太多了。
If you need particular output, the doc page you mentioned offers few suggestions:
如果您需要特定的输出,您提到的文档页面提供了一些建议:
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.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
out
anderr
files in a separate tab and let editor automatically refresh it for you, or do a simplepy.test; cat out.txt
shell command to run your test.
assert False, "dumb assert to make PyTest print my stuff"
在函数的末尾插入,由于测试失败,您将看到输出。您有 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)
您可以在单独的选项卡中打开
out
和err
文件,让编辑器自动为您刷新,或者执行简单的py.test; cat out.txt
shell 命令来运行您的测试。
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 PyTest
muted 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 atexit
module allows me to print stuff afterPyTest
released 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 PyTest
is 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=sys
should work. If you want to capture standard out inside a test, refer to the capsys fixture.
根据pytest docs,pytest --capture=sys
应该可以工作。如果您想在测试中捕获标准输出,请参阅 capsys 夹具。
回答by lmiguelvargasf
Short Answer
简答
Use the -s
option:
使用-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.
在测试执行期间,任何发送到stdout和stderr 的输出都会被捕获。如果测试或设置方法失败,其相应的捕获输出通常会与失败回溯一起显示。
pytest
has the option --capture=method
in which method
is per-test capturing method, and could be one of the following: fd
, sys
or no
. pytest
also has the option -s
which 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
,sys
或no
。pytest
还有一个选项-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 pytest
can perform capturing:
有两种方法pytest
可以执行捕获:
file descriptor (FD) level capturing(default): All writes going to the operating system file descriptors 1 and 2 will be captured.
sys level capturing: Only writes to Python files sys.stdout and sys.stderr will be captured. No capturing of writes to filedescriptors is performed.
文件描述符 (FD) 级别捕获(默认):将捕获所有写入操作系统文件描述符 1 和 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 PyTest
print in VSCode's console while running/debugging the unit test from there. This can be done with the following launch.json
configuration. Given .venv
the 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"
]
}
]
}