我有这个函数定义:
def interactive_mode():
parking_query = Query()
while(True):
query = input()
if query == 'exit':
return -1
else:
parking_query.process(query)
我需要使用 pytest 测试这个函数,当我的测试文件中的 input() 处于无限循环内时,如何模拟它?
此外,在模拟输入后,我需要从 stdout 捕获每个输入的输出,这可以在 pytest 中使用 capsys 来完成。
我尝试过做的事情:
1.
monkeypatch.setattr('sys.stdin', io.StringIO(query))
这会给出 EOF 错误,不起作用!
2.
from unittest.mock import Mock
mock_stdin = Mock()
mock_stdin.readline = Mock(io.StringIO(query))
monkeypatch.setattr('sys.stdin', io.StringIO(query))
当我运行pytest
时无限卡住
我的测试功能:
def test_interactive_mode(capsys, monkeypatch):
'''
Tests the interactive_mode() method by mocking
stdin using monkeypatch and reading stdout using capsys
'''
testcases = [
{
'input': [
'input query'
],
'output': [
'expected output response to query'
]
}
]
for case in testcases:
for i, query in enumerate(case['input']):
with mock.patch.object(builtins, 'input', lambda : query):
# mock_stdin = Mock()
# mock_stdin.readline = Mock(io.StringIO(query))
# monkeypatch.setattr('sys.stdin', io.StringIO(query))
return_value = interactive_mode()
if return_value == -1:
break
captured = capsys.readouterr()
assert captured.out == case['output'][i] + '\n'
最佳答案
找到了一种解决问题的奇特方法,可以达到目的,但不建议作为完美的解决方案!
def test_interactive_mode(capsys, monkeypatch):
'''
Tests the interactive_mode() method by mocking
stdin using monkeypatch and reading stdout using capsys
'''
testcases = [
{
'input': [
'input query'
],
'output': [
'expected output response to query'
]
}
]
for case in testcases:
for i, query in enumerate(case['input']):
with mock.patch('builtins.input', side_effect=[query, 'exit']):
return_value = interactive_mode()
if return_value == -1:
break
captured = capsys.readouterr()
assert captured.out == case['output'][i] + '\n'
关于python - 如何使用 pytest 测试交互式 python 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60694950/