我尝试使用pytest
进行TDD(测试驱动开发)。
当我使用pytest
时,print
不会print
到控制台。
我正在使用pytest my_tests.py
来运行它。
documentation
似乎表示默认情况下应该有效:http://pytest.org/latest/capture.html
可是:
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.
没有任何内容打印到我的标准输出控制台(只是正常的进度和多少次测试通过/失败)。
我测试的脚本包含print:
class Blogger(Site):
get_links(self, posts):
print len(posts) # It won't get printed in the test.
在unittest
模块中,默认情况下会打印所有内容,这正是我所需要的。但是,我希望出于其他原因使用pytest
。
是否有人知道如何显示打印报表?
答案 0 :(得分:132)
默认情况下,py.test
会捕获标准输出的结果,以便它可以控制打印输出的方式。如果它没有做到这一点,它会喷出很多文本,而没有测试打印该文本的背景。
但是,如果测试失败,它将在结果报告中包含一个部分,显示在该特定测试中打印到标准输出的内容。
例如,
def test_good():
for i in range(1000):
print(i)
def test_bad():
print('this should fail!')
assert False
结果如下:
>>> 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 ======================
请注意Captured stdout
部分。
如果您希望在执行时看到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 ======================
答案 1 :(得分:41)
使用-s
选项将打印所有功能的输出,这可能太多了。
如果您需要特定输出,您提到的文档页面提供的建议很少:
在功能结束处插入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命令来运行测试。
这是做东西的相当骇人的方式,但可能是你需要的东西:毕竟,TDD意味着你把东西弄得乱七八糟,当它准备就绪时保持干净和安静: - )。
答案 2 :(得分:10)
当PyTest
字面上一切时,我需要准确打印关于跳过测试的重要警告。
我不想通过测试来发送信号,所以我做了如下黑客攻击:
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)
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$
即使PyTest
处于静音模式,也会打印消息,如果您运行py.test -s
的内容,则不打印,因此所有内容都已经过很好的测试。
答案 3 :(得分:4)
根据pytest docs,pytest --capture=sys
应该有效。如果您想在测试中捕获标准输出,请参阅capsys fixture。
答案 4 :(得分:3)
使用-s
选项:
pytest -s
来自the docs:
在测试执行期间,将捕获发送到 stdout 和 stderr 的所有输出。如果测试或设置方法失败,则通常会显示其相应的捕获输出以及失败回溯。
pytest
具有选项--capture=method
,其中method
是每次测试的捕获方法,并且可以是以下之一:fd
,sys
或no
。 pytest
还具有选项-s
,它是--capture=no
的快捷方式,该选项使您可以在控制台中查看打印语句。
pytest --capture=no # show print statements in console
pytest -s # equivalent to previous command
pytest
可以通过两种方式进行捕获:
文件描述符(FD)级别捕获(默认设置):将捕获所有对操作系统文件描述符1和2的写操作。
sys级捕获:仅捕获对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
答案 5 :(得分:2)
我最初来这里是为了找到如何在VSCode的控制台中运行{/ {1}}进行打印/调试单元测试的同时进行打印的方法。这可以通过以下PyTest
配置来完成。给launch.json
虚拟环境文件夹。
.venv
答案 6 :(得分:1)
这是我所知道的将单个语句打印到 sys.stdout
的最干净的方法(无需人为地使测试失败或启用 -s
选项)-您可以看到所需的特定输出,什么也没有更多:
将内置参数 capsys
添加到您的测试函数中。
在您的代码中,只需插入:
with capsys.disabled():
print("this output will not be captured and go straight to sys.stdout")
请参阅 https://buildmedia.readthedocs.org/media/pdf/pytest/latest/pytest.pdf(2.11 如何捕获 stdout/stderr 输出)。
答案 7 :(得分:0)
您也可以通过 Pycharm GUI 进行设置:转到 Run > Edit Configurations
。在那里,选择要为其启用打印语句的测试并将 -s
添加到 Additional Arguments
字段。
我是这样做的,因为虽然我主要使用 Pycharm 调试器来调试我的 pytest 函数(即通过 GUI),但我的特定用例还要求我知道代码中其他地方发生了什么,并且打印语句可能会出现可以派上用场。