使用公共测试函数中的pytestfixture

2024-07-03 06:32:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些基于unittest的代码currently looks like this

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(...)

run_prog调用测试中的“main”程序并手动捕获其标准输出

我正在将这个项目转换为pytest,但是最后一部分已经突破了我对pytest夹具理解的极限

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

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

def test_myoutput(capfd):
    do_something
    captured = capsys.readouterr()
    assert captured.out == "hello\n"
    assert captured.err == "world\n"

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

有没有办法从我的run_prog助手中“调用”该装置?或者我需要将capfd添加到所有42个测试中,并将其传递给run_prog


Tags: runtestselfdatapytestmaindefstdout
2条回答

您可以定义自动使用装置,该装置将CaptureFixture对象(由capsys装置返回)存储为实例属性:

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's answer的一个小小的变化,它对capsysfixture的范围提供了更多的控制

它使用^{}在函数调用时检索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!")

相关问题 更多 >