在输入提示符上测试 python 标准输出



以下方法的测试检查提示中的标准输出是否正确。

当调用"input()"时,它会等待用户按回车键并中断。测试通过自动按键"输入"通过。

这是黑客,必须有更好的方法来测试这种方法。

方法

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语句的stdout,因此请添加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:两次

测试prompt()return_value在现实生活中应该足够了。

如果您真的想同时模拟输入和输出,则只剩下 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:

最新更新