如何打印到控制台在pytest?

我试图使用TDD(测试驱动开发)与pytest。 当我使用print时,pytest将不会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.

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

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

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

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

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

315190 次浏览

默认情况下,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 ======================

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

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

  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.txt shell命令来运行测试

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

我需要打印关于跳过测试的重要警告,准确地说,当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$

Message即使在PyTest处于静默模式时也会被打印,如果使用py.test -s运行内容则会被打印为,因此一切都已经过了良好的测试。

根据pytest文档pytest --capture=sys应该工作。如果您想在测试中捕获标准,请参考capsys夹具。

使用-s选项:

pytest -s

详细的回答

的文档:

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

pytest有选项--capture=method,其中method是每个测试捕获方法,可以是以下之一:fdsysnopytest还有一个选项-s,它是--capture=no的快捷方式,这个选项将允许你在控制台中查看打印语句。

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

设置捕获方法或禁用捕获

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

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

  2. 系统级别捕获:只写入Python文件sys. exeStdout和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

我最初来到这里是为了找到如何在VSCode的控制台中打印PyTest,同时从那里运行/调试单元测试。这可以用下面的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"
]
}
]
}

这是我所知道的将单个语句打印到sys.stdout的最干净的方式(没有人为地使测试失败或启用-s选项)-你可以看到你想要的特定输出,而不是其他:

  1. 将内置参数capsys添加到测试函数中。(这意味着你将capsys添加到参数列表中,例如:
def test_function(existing_parameters, capsys):
  1. 在你的代码中,只需插入:
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输出)。

你也可以通过Pycharm GUI来设置:转到Run > Edit Configurations。在那里,选择要为其启用打印语句的测试,并将-s添加到Additional Arguments字段。

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

我通常使用这个命令:-

pytest -v -rs --html=report.html --self-contained-html test_Suite.py -s

上面的命令还生成了一个report.html文件,所有的print语句都被捕获并保存在其中。最后的-s也会将打印语句显示到终端中。

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

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

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

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

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

如果你正在使用pytest.ini,考虑使用:

[pytest]
...
addopts = --capture=no
...

如果你从一个基于你pytest.ini的IDE扩展运行你的测试,这很好