如何使用pytest捕获Python input()函数的提示信息?
如何捕获input()的提示信息用于pytest测试?
问题场景
现有如下Python函数:
def myFunction(argument: str) -> None: doStuff() result = input(f'{complicated_logic_involving_argument}: ') doOtherStuff()
需要用pytest测试该函数,同时验证不同参数对应的提示内容是否正确。但使用capsys/capfd尝试捕获input()的提示时,无法在输出快照中找到对应内容,测试代码如下:
@pytest.mark.parametrize(('argument', 'prompt'), ( ('firstValue', 'Expected Prompt'), )) def test_myFunction(argument: str, prompt: str, monkeypatch, capsys) -> None: monkeypatch.setattr('builtins.input', lambda _: 'whatever') myFunction(argument) snapshot = capsys.readouterr() assert prompt in snapshot.out
问题原因
你替换builtins.input的lambda函数跳过了原input函数的核心逻辑:原input函数会将传入的prompt参数输出到标准输出,再读取输入;而你的lambda仅返回预设输入值,完全没有执行prompt的输出步骤,因此capsys/capfd无法捕获到任何提示内容。
正确解决方案
无需捕获输出,直接通过记录mock input函数的调用参数来验证提示内容。具体实现如下:
import pytest from your_module import myFunction # 替换为实际模块名 @pytest.mark.parametrize(('argument', 'expected_prompt'), ( ('firstValue', 'Expected Prompt'), )) def test_myFunction(argument: str, expected_prompt: str, monkeypatch) -> None: # 定义mock input函数,保存传入的prompt参数 captured_prompt = None def mock_input(prompt: str) -> str: nonlocal captured_prompt captured_prompt = prompt return 'whatever' monkeypatch.setattr('builtins.input', mock_input) myFunction(argument) # 验证捕获的prompt是否符合预期 assert captured_prompt == expected_prompt
额外说明
如果你的代码是通过单独的print()语句输出提示,再调用无参数的input(),那么capsys/capfd可以正常捕获输出。但在当前场景中,提示作为input的参数传入,只有原input函数会处理其输出,替换input后该步骤失效,因此必须通过记录mock函数的参数来完成验证。
内容的提问来源于stack exchange,提问作者Nuno
相关产品推荐
相关产品推荐

