我试着在pytest中使用TDD(测试驱动开发)。 当我使用print时,pytest将不会打印到控制台。

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

文档似乎说默认情况下它应该工作: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.

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

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

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

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

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


当前回答

默认为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 ======================

注意俘获标准输出部分。

如果您希望在执行语句时看到打印语句,可以将-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 ======================

其他回答

默认为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 ======================

注意俘获标准输出部分。

如果您希望在执行语句时看到打印语句,可以将-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 ======================

这是我所知道的打印单个语句到sys的最简洁的方法。Stdout(不人为地使你的测试失败或启用-s选项)-你可以看到你想要的特定输出,仅此:

将内置参数capsys添加到测试函数中。(这意味着您将capsys添加到参数列表中,例如:

def test_function(existing_parameters, 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输出)。

已经有很多很好的答案,但我想分享一下为什么在运行pytest时无法获得日志。

一个重要的注意事项是,当您编写函数时,每个测试用例必须以test_前缀开始。否则,在使用pytest时就不会有打印语句。

至于命令,我使用下面的命令来获得非常全面的日志:

python -m pytest -v -rs <particular_file.py> -s -o log_cli-level=DEBUG

通过确保您有正确的函数名并使用我的命令,您应该能够确定地看到控制台日志。

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

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

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 and err files in a separate tab and let editor automatically refresh it for you, or do a simple py.test; cat out.txt shell command to run your test.

这是一种相当粗鄙的做事方式,但它可能是你需要的东西:毕竟,TDD意味着你把东西弄得乱七八糟,然后在它准备好时让它干净安静:-)。

你也可以通过Pycharm GUI来设置:去运行>编辑配置。在那里,选择要为其启用打印语句的测试,并在Additional Arguments字段中添加-s。

我这样做是因为虽然我主要使用Pycharm调试器来调试我的pytest函数(即通过GUI),但我的特定用例也要求我知道代码中其他地方发生了什么,打印语句可以为此派上用场。