python - 在输入提示下测试 python stdout
问题描述
以下方法的测试检查提示中的标准输出是否正确。
当 'input()' 被调用时,它会等待用户按下回车键并中断。测试通过自动按键“输入”来通过。
这很hacky,必须有更好的方法来测试这种方法。
方法:
class GameDisplay:
@staticmethod
def prompt(text):
input_value = input(text)
return input_value
测试:
from pynput.keyboard import Key, Controller
class TestGameDisplay(unittest.TestCase):
@patch('sys.stdout', new_callable=StringIO)
def test_prompt_output(self, mock_stdout):
keyboard = Controller()
keyboard.press(Key.enter)
self.gameDisplay.prompt('Choose 0: ')
keyboard.release(Key.enter)
self.assertEqual( mock_stdout.getvalue(), 'Choose 0: ')
if __name__ == '__main__':
unittest.main()
输出:
由于按下回车而换行。
...................................
............................................
----------------------------------------------------------------------
Ran 79 tests in 0.113s
OK
测试修复尝试:
@patch('sys.stdout', new_callable=StringIO)
@patch('builtins.input', return_value='0')
def test_prompt_output(self, mock_stdout, input):
self.gameDisplay.prompt('Choose 0: ')
self.assertEqual( mock_stdout.getvalue(), 'Choose 0: ')
输出:
FAIL: test_prompt_output (tests.test_game_display.TestGameDisplay)
self.assertEqual( mock_stdout.getvalue(), 'Choose 0: ')
AssertionError: <MagicMock name='input.getvalue()' id='4675607744'> != 'Choose 0: '
----------------------------------------------------------------------
Ran 79 tests in 0.015s
FAILED (failures=1)
解决方案
mock_stdout 只捕获print
语句的标准输出,所以添加print(text)
class GameDisplay:
@staticmethod
def prompt(text):
input_value = input(text)
print(text)
return input_value
这段代码经过测试并按预期工作
@mock.patch('sys.stdout', new_callable=StringIO)
@mock.patch('__builtin__.input', return_value='0')
def test_prompt_output3(self, mock_input, mock_stdout):
p = GameDisplay.prompt('Choose 0: ')
self.assertEqual(p, '0')
self.assertEqual(mock_stdout.getvalue(), 'Choose 0: \n')
但随后它会打印选择 0: 两次
在现实生活中测试 return_valueprompt()
应该足够了。
如果您真的想同时模拟输入和输出,则只剩下 1 个选项。
这会做,只要你不同时模拟print
:
print(text)
input_value = input()
或者采取一种疯狂的方式,伪造标准输出:
mock_stdout = StringIO('Choose 0: ')
p = GameDisplay.prompt('Choose 0: ')
self.assertEqual(mock_stdout.getvalue(), 'Choose 0: ')
或者这类似于将 return_value 分配给模拟对象:
with mock.patch('sys.stdout', new=StringIO("xxx")) as mock_stdout:
推荐阅读
- angular - “FadeblockComponent”类型上不存在属性“currentState”
- sql-server - 如何以有效的方式将数据库从一台服务器自动复制到另一台服务器(不是备份和恢复)
- wpf - 当 MenuItem 具有自定义 ControlTemplate 并在单独的 XAML 文件中定义时,如何将 MenuItem 与子 MenuItems 一起使用?
- xaml - DatePicker dd/mm/yyyy 格式显示 dd-mm-yyyy,为什么
- python - 将各种大小的数据集拆分为单独的数据帧
- python-3.x - 我只是想在 pyinstaller 中编译我的脚本并遇到了一些错误。我该如何修复它们?
- sql - SQL 查询 - 基于条件迭代
- java - 如何获得下周的第一天?
- android - 我的 PushNotification 不在个人频道 ID 中运行
- php - 内含特殊字符的 PHP 文件夹名称