基于Python的cmd模块为交互式shell创建自动化测试 [英] Create automated tests for interactive shell based on Python's cmd module

查看:318
本文介绍了基于Python的cmd模块为交互式shell创建自动化测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Python 3和cmd模块构建一个交互式shell.我已经使用py.test编写了简单的单元测试,以测试各个功能,例如do_ *功能.我想创建更全面的测试,通过模拟用户的输入与外壳本身进行实际交互.例如,如何测试以下模拟会话:

I am building an interactive shell using Python 3 and the cmd module. I have already written simple unit tests using py.test to test the individual functions, such as the do_* functions. I'd like to create more comprehensive tests that actually interact with the shell itself by simulating a user's input. 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:>

推荐答案

您可以mock input或传递到cmd的输入流来注入用户输入,但是我发现通过onecmd() API方法并信任Cmd如何读取输入.这样,您就不必关心Cmd如何执行肮脏的工作并直接通过用户命令进行测试:我同时通过控制台和套接字使用cmd,并且我不在乎流来自何处.

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. 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.

此外,我使用onecmd()甚至可以测试do_*(有时是help_*)方法,并使测试与代码的耦合度降低.

Moreover I use onecmd() to test even do_* (and occasionally help_*) methods and make my test less coupled to the code.

按照一个简单的示例说明如何使用它. create()_last_write()是用于构建MyCLI实例并分别获取最后一行输出的辅助方法.

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.

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())

请注意,如果您的cli应该终止,请onecmd()返回True,否则请False.

Take care that onecmd() return True if your cli should terminate, False otherwise.

这篇关于基于Python的cmd模块为交互式shell创建自动化测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆