How can I see normal print output created during pytest run?
有时,我只想在代码中插入一些打印语句,看看当我练习它时会打印出什么。我通常的"练习"方法是使用现有的Pytest测试。但当我运行这些程序时,我似乎看不到任何标准输出(至少在我的IDE pycharm中是这样)。
有没有一种简单的方法可以在Pytest运行期间查看标准输出?
在对已接受答案的乐观评论中,乔问:
Is there any way to print to the console AND capture the output so that it shows in the junit report?
在Unix中,这通常被称为teeing。理想情况下,teeing而不是捕获将是py.test的默认值。非理想情况下,py.test和任何现有的第三方py.test插件(我知道,无论如何)都不支持teeing——尽管python非常支持现成的teeing。
猴子修补py.test来做任何不支持的事情都是不平凡的。为什么?因为:
- 大多数py.test功能都锁定在不打算从外部导入的私有
_pytest 包之后。尝试在不知道自己在做什么的情况下这样做通常会导致公共的pytest 包在运行时引发一些模糊的异常。多谢,小派。测试。你的架构非常强大。 - 即使您确实知道如何安全地对私有
_pytest API进行monkey修补,也必须在运行由外部py.test 命令运行的公共pytest 包之前进行。您不能在插件(例如,测试套件中的顶级conftest 模块)中执行此操作。当py.test懒散地开始动态导入插件时,任何你想要安装monkey补丁的py.test类都已经被实例化了——你没有访问该实例的权限。这意味着,如果您希望有意义地应用monkey补丁,就不能再安全地运行外部py.test 命令。相反,您必须用一个定制的SETUPTOOLStest 命令来包装该命令的运行,该命令(按顺序)如下: - monkey补丁私有
_pytest API。 - 调用public
pytest.main() 函数来运行py.test 命令。
这个答案是monkey补丁py.test的
为什么这么做?我现在就告诉你。我的py.test-driven测试套件包含缓慢的功能测试。显示这些测试中的stdout是有益且可靠的,防止leycec在另一个长时间运行的功能测试连续数周没有做任何事情的时候达到
在我们开始之前,这个答案假设您已经有了一个自定义的设置工具
不要安装py test runner,它是一个提供自定义安装工具的第三方安装工具插件,
假设您遵循上面强调的手动集成中的说明,那么您的代码库现在应该包含一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | class PyTest(TestCommand): . . . def run_tests(self): # Import the public"pytest" package *BEFORE* the private"_pytest" # package. While importation order is typically ignorable, imports can # technically have side effects. Tragicomically, that is the case here. # Importing the public"pytest" package establishes runtime # configuration required by submodules of the private"_pytest" package. # The former *MUST* always be imported before the latter. Failing to do # so raises obtuse exceptions at runtime... which is bad. import pytest from _pytest.capture import CaptureManager, FDCapture, MultiCapture # If the private method to be monkey-patched no longer exists, py.test # is either broken or unsupported. In either case, raise an exception. if not hasattr(CaptureManager, '_getcapture'): from distutils.errors import DistutilsClassError raise DistutilsClassError( 'Class"pytest.capture.CaptureManager" method _getcapture() ' 'not found. The current version of py.test is either ' 'broken (unlikely) or unsupported (likely).' ) # Old method to be monkey-patched. _getcapture_old = CaptureManager._getcapture # New method applying this monkey-patch. Note the use of: # # *"out=False", *NOT* capturing stdout. # *"err=True", capturing stderr. def _getcapture_new(self, method): if method =="no": return MultiCapture( out=False, err=True, in_=False, Capture=FDCapture) else: return _getcapture_old(self, method) # Replace the old with the new method. CaptureManager._getcapture = _getcapture_new # Run py.test with all passed arguments. errno = pytest.main(self.pytest_args) sys.exit(errno) |
要启用此monkey补丁,请运行py.test,如下所示:
1 | python setup.py test -a"-s" |
现在将捕获stderr而不是stdout。漂亮!
把上面的monkey补丁扩展到tee stdout和stderr,留给读者做一个充满空闲时间的练习。
根据Pytest文档,Pytest版本3可以临时禁用测试中的捕获:
1 2 3 4 5 | def test_disabling_capturing(capsys): print('this output is captured') with capsys.disabled(): print('output not captured, going directly to sys.stdout') print('this output is also captured') |
运行测试时,使用
1 | py.test exampletest.py -s |
有关控制台中的更多信息,请尝试使用
1 2 3 4 5 | pytest -v -s scriptname(for single test script) pytest -v -s (for complete module/package) pytest -v -s scriptname::function(indiviual function) |
如果您使用的是PyCharm IDE,那么您可以使用运行工具栏运行单个测试或所有测试。运行工具窗口显示应用程序生成的输出,您可以将其中的所有打印语句作为测试输出的一部分。