[英]Create automated tests for interactive shell based on Python's cmd module
I am building an interactive shell using Python 3 and the cmd module. 我正在使用Python 3和cmd模块构建交互式shell。 I have already written simple unit tests using py.test to test the individual functions, such as the do_* functions.
我已经使用py.test编写了简单的单元测试来测试各个函数,例如do_ *函数。 I'd like to create more comprehensive tests that actually interact with the shell itself by simulating a user's input.
我想创建更全面的测试,通过模拟用户的输入实际上与shell本身进行交互。 For example, how could I test the following simulated session:
例如,我如何测试以下模拟会话:
bash$ console-app.py
md:> show options
Available Options:
------------------
HOST The IP address or hostname of the machine to interact with
PORT The TCP port number of the server on the HOST
md:> set HOST localhost
HOST => 'localhost'
md:> set PORT 2222
PORT => '2222'
md:>
You can mock
input
or input stream passed to cmd to inject user input but I find more simple and flexible test it by onecmd()
Cmd
API method and trust how Cmd
read input. 您可以
mock
传递给cmd的input
或输入流以注入用户输入,但我发现通过onecmd()
Cmd
API方法更简单灵活地测试它并信任Cmd
如何读取输入。 In this way you cannot care how Cmd
do the dirty work and test directly by users command: I use cmd
both by console and socket and this I cannot care where the stream come from. 通过这种方式,您无法关心
Cmd
如何通过用户命令直接执行脏工作和测试:我通过控制台和套接字使用cmd
,这我不关心流来自何处。
Moreover I use onecmd()
to test even do_*
(and occasionally help_*
) methods and make my test less coupled to the code. 此外,我使用
onecmd()
来测试甚至do_*
(偶尔help_*
)方法,并使我的测试更少地耦合到代码。
Follow a simple example of how I use it. 按照我如何使用它的简单示例。
create()
and _last_write()
are helper methods to build a MyCLI
instance and take the last output lines respectively. create()
和_last_write()
是帮助方法,用于构建MyCLI
实例并分别获取最后一行输出。
from mymodule import MyCLI
from unittest.mock import create_autospec
class TestMyCLI(unittest.TestCase):
def setUp(self):
self.mock_stdin = create_autospec(sys.stdin)
self.mock_stdout = create_autospec(sys.stdout)
def create(self, server=None):
return MyCLI(stdin=self.mock_stdin, stdout=self.mock_stdout)
def _last_write(self, nr=None):
""":return: last `n` output lines"""
if nr is None:
return self.mock_stdout.write.call_args[0][0]
return "".join(map(lambda c: c[0][0], self.mock_stdout.write.call_args_list[-nr:]))
def test_active(self):
"""Tesing `active` command"""
cli = self.create()
self.assertFalse(cli.onecmd("active"))
self.assertTrue(self.mock_stdout.flush.called)
self.assertEqual("Autogain active=False\n", self._last_write())
self.mock_stdout.reset_mock()
self.assertFalse(cli.onecmd("active TRue"))
self.assertTrue(self.mock_stdout.flush.called)
self.assertEqual("Autogain active=True\n", self._last_write())
self.assertFalse(cli.onecmd("active 0"))
self.assertTrue(self.mock_stdout.flush.called)
self.assertEqual("Autogain active=False\n", self._last_write())
def test_exit(self):
"""exit command"""
cli = self.create()
self.assertTrue(cli.onecmd("exit"))
self.assertEqual("Goodbay\n", self._last_write())
Take care that onecmd()
return True
if your cli should terminate, False
otherwise. 如果你的cli应该终止,请注意
onecmd()
返回True
,否则返回False
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.