编写一个pytest函数来检查控制台(stdout)上的输出。

42

这篇文章描述了如何使用pytest来捕获控制台输出。我尝试了下面的代码,但是出现了一个错误

import sys
import pytest
def f(name):
    print "hello "+ name

def test_add(capsys):
    f("Tom")
    out,err=capsys.readouterr()
    assert out=="hello Tom"


test_add(sys.stdout)

输出:

python test_pytest.py 
hello Tom
Traceback (most recent call last):
  File "test_pytest.py", line 12, in <module>
    test_add(sys.stdout)
  File "test_pytest.py", line 8, in test_add
    out,err=capsys.readouterr()
AttributeError: 'file' object has no attribute 'readouterr'

我还尝试将capsys替换为capfd,但是出现了相同的错误。
出了什么问题,该如何修复?
2个回答

62
使用capfd装置。 示例:
def test_foo(capfd):
    foo()  # Writes "Hello World!" to stdout
    out, err = capfd.readouterr()
    assert out == "Hello World!"

请参考:http://pytest.org/en/latest/fixture.html 以获取更多详细信息。
并且请查看:py.test --fixtures 以获取内置的固定装置列表。
您的示例存在一些问题。这是一个已经纠正的版本:
def f(name):
    print("hello " + name)


def test_f(capfd):
    f("Tom")

    out, err = capfd.readouterr()
    assert out == "hello Tom\n"

注意:

  • 不要使用sys.stdout -- 使用pytest提供的capfd fixture。
  • 运行测试用例的命令为:py.test foo.py

测试运行输出:

$ py.test foo.py
====================================================================== test session starts ======================================================================
platform linux2 -- Python 2.7.5 -- pytest-2.4.2
plugins: flakes, cache, pep8, cov
collected 1 items 

foo.py .

=================================================================== 1 passed in 0.01 seconds ====================================================================

还要注意:

  • 在测试模块中不需要运行你的测试函数py.test命令行工具和测试运行器)会为你执行这些操作。

py.test主要有三个功能:

  1. 收集你的测试
  2. 运行你的测试
  3. 显示统计信息和可能的错误

默认情况下,py.test会在你的测试模块中查找(可配置的iirctest_foo.py测试模块和test_foo()测试函数。


这并没有帮助。我收到了相同的错误信息。我已经将代码粘贴在上面供您参考。 - brain storm
你使用的 pytest 版本是什么?尝试升级一下。这在我所有的单元测试中都能正常工作并得到验证。 - James Mills
你的代码中没有调用 test_f(capfd) 函数,这样可以吗? - brain storm
测试运行器和命令行工具py.test可以为您完成这项工作。它主要执行三个任务:1)收集所有测试;2)运行所有测试;3)生成统计信息和错误输出。 - James Mills
1
它如何知道要运行哪个测试函数?所有测试函数都以test_xxx命名吗? - brain storm
1
正确。这是可配置的IRRC,但默认情况下会在“test_foo.py”模块中查找“test_foo()”函数,并在这些测试模块中执行。 - James Mills

8
问题出在您在第一个代码片段的最后明确调用测试函数上:

问题出在您在第一个代码片段的最后明确调用测试函数上:

test_add(sys.stdout)

你不应该这样做;pytest负责调用你的测试函数。 当它这样做时,它会识别名称capsys(或者capfd),并自动为您提供一个适合的pytest内部对象作为调用参数。 (pytest文档中给出的示例已经很完整了。) 该对象将提供所需的readouterr()函数。 sys.stdout没有该函数,这就是为什么你的程序失败的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接