使用公共测试函数中的pytest夹具



我有一些基于unittest的代码,目前看起来是这样的:

class TestMain(TestCase):
def run_prog(self, args):
with TemporaryFile() as stdout:
old_stdout = sys.stdout
try:
main.main()
stdout.seek(0)
stdout_data = stdout.read()
finally:
sys.stdout = old_stdout
return stdout_data
def test_one(self):
out = self.run_prog(...)
def test_two(self):
out = self.run_prog(...)
def test_three(self):
out = self.run_prog(...)

CCD_ 2调用";主";程序正在测试中,并手动捕获其stdout。

我正在将这个项目转换为pytest,但最后一篇文章已经突破了我对pytest fixture的理解极限。

我知道pytest完全支持捕获stdout/stderr,我想利用这一点。

问题是,他们的例子在测试功能级别上工作:

def test_myoutput(capfd):
do_something
captured = capsys.readouterr()
assert captured.out == "hellon"
assert captured.err == "worldn"

在我的例子中,run_prog被使用了42次,所以我尝试从run_prog开始使用fixture——理想情况下,调用函数不需要使用capsys/capfd

有没有办法";调用";我的run_prog助手的固定装置?还是我需要将capfd添加到所有42个测试中,并将其传递给run_prog

您可以定义一个autouse fixture,它将把CaptureFixture对象(由capsysfixture返回(存储为实例属性:

class TestMain(TestCase):
@pytest.fixture(autouse=True)
def inject_capsys(self, capsys):
self._capsys = capsys
def run_prog(self, args):
main.main()
return self._capsys.out
def test_out(self):
assert self.run_prog('spam') == 'eggs'

每次测试都将重新运行TestMain.inject_capsys夹具,以确保测试隔离(test_one的输出不会在test_two等中泄漏(。

这里对hoefling的答案有一个细微的变化,它对capsys固定装置的范围有了更多的控制。

它使用request.getfixturevalue()在函数调用时检索fixture:

import pytest
import sys
class TestMain:
@pytest.fixture(autouse=True)
def inject_request(self, request):
self.request = request
def run_prog(self, message):
capfd = self.request.getfixturevalue('capfd')
sys.stdout.write(message)
captured = capfd.readouterr()
assert captured.out == message
def test_one(self):
self.run_prog("Hello world!")

最新更新