You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pytest capsys捕获print输出失败,遇AttributeError/TypeError错误求助

问题:使用pytest capsys fixture捕获print输出时遇属性错误和参数错误

问题场景

尝试用pytest的capsys fixture捕获代码中print语句的输出,但遇到两类错误:

  • 通过自动注入的fixture给测试类实例绑定capsys时,报AttributeError: 'TestCoffeeMachine' object has no attribute 'capsys'
  • 直接在测试方法中传入capsys参数时,报TypeError: test_cost_calculation() missing 1 required positional argument: 'capsys'

相关代码

导入与测试类定义

import pytest
import unittest

from CoffeeMachine import CoffeeMachine

class TestCoffeeMachine(unittest.TestCase):
    def setUp(self):
        self.coffee_1 = CoffeeMachine(200, 300, 20, 0)

自动注入的Fixture尝试

@pytest.fixture(autouse=True)
def _pass_fixtures(self, capsys):
    self.capfd = capsys

第一种测试方法(报错)

def test_cost_calculation(self):
    return_value = self.coffee_1.cost_calculation(CoffeeMachine.coffee_type[0], 10.50)
    captured = self.capsys.readouterr()
    self.assertEqual("Total Money Loaded is: 10.5", captured.out)
    self.assertEqual(return_value[0], True)
    self.assertEqual(return_value[1], 4.95)

第二种测试方法(报错)

def test_cost_calculation(self, capsys):
    return_value = self.coffee_1.cost_calculation(CoffeeMachine.coffee_type[0], 10.50)
    captured = capsys.readouterr()
    self.assertEqual("Total Money Loaded is: 10.5", captured.out)
    self.assertEqual(return_value[0], True)
    self.assertEqual(return_value[1], 4.95)

错误信息

第一种方法的错误

captured = self.capsys.readouterr()
AttributeError: 'TestCoffeeMachine' object has no attribute 'capsys'

第二种方法的错误

Traceback (most recent call last):
TypeError: test_cost_calculation() missing 1 required positional argument: 'capsys'

问题原因与解决方案

核心原因

  1. 第一种方法中,fixture里将capsys赋值给了self.capfd,但测试方法中访问的是self.capsys,变量名不匹配;同时unittest测试类的实例在pytest fixture中的注入逻辑需要调整。
  2. 第二种方法中,unittest的测试方法不支持直接接收pytest fixture作为参数,因为unittest框架调用测试方法时不会自动注入pytest的fixture参数。

解决方案1:改用纯pytest测试风格(推荐)

放弃继承unittest.TestCase,使用pytest原生的测试类写法,这样可以直接使用fixture参数:

import pytest
from CoffeeMachine import CoffeeMachine

class TestCoffeeMachine:
    def setup_method(self):
        # 替代unittest的setUp
        self.coffee_1 = CoffeeMachine(200, 300, 20, 0)

    def test_cost_calculation(self, capsys):
        return_value = self.coffee_1.cost_calculation(CoffeeMachine.coffee_type[0], 10.50)
        captured = capsys.readouterr()
        # 注意strip()处理输出中的换行符
        assert "Total Money Loaded is: 10.5" == captured.out.strip()
        assert return_value[0] is True
        assert return_value[1] == 4.95

解决方案2:保留unittest.TestCase的兼容写法

如果需要继续使用unittest测试类,可将fixture作用域设为类级别,并绑定到类属性:

import pytest
import unittest
from CoffeeMachine import CoffeeMachine

@pytest.fixture(autouse=True, scope='class')
def _pass_fixtures(cls, capsys):
    # cls指向测试类本身
    cls.capsys = capsys

class TestCoffeeMachine(unittest.TestCase):
    def setUp(self):
        self.coffee_1 = CoffeeMachine(200, 300, 20, 0)

    def test_cost_calculation(self):
        return_value = self.coffee_1.cost_calculation(CoffeeMachine.coffee_type[0], 10.50)
        captured = self.capsys.readouterr()
        self.assertEqual("Total Money Loaded is: 10.5", captured.out.strip())
        self.assertEqual(return_value[0], True)
        self.assertEqual(return_value[1], 4.95)

内容的提问来源于stack exchange,提问作者Nirmalgautham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:01:07