6

Python 3 と cmd モジュールを使用してインタラクティブ シェルを構築しています。do_* 関数などの個々の関数をテストするために、py.test を使用して簡単な単体テストを既に作成しました。ユーザーの入力をシミュレートしてシェル自体と実際に対話する、より包括的なテストを作成したいと考えています。たとえば、次のシミュレートされたセッションをテストするにはどうすればよいですか。

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:>
4

2 に答える 2

5

ユーザー入力を挿入するためにcmdに渡された入力ストリームを入力することもできますmock inputが、APIメソッドでよりシンプルで柔軟なテストを見つけ、入力の読み取りonecmd() Cmd方法を信頼します。Cmdこの方法でCmdは、ダーティな作業をどのように実行し、ユーザー コマンドで直接テストするかを気にすることはできませんcmd。コンソールとソケットの両方を使用しますが、ストリームがどこから来るかは気にしません。

さらに、私はメソッドをonecmd()偶数do_*(場合help_*によっては) テストし、テストがコードに結合されないようにします。

私がそれをどのように使用するかの簡単な例に従ってください。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())

cli を終了する必要がある場合はonecmd()戻りますが、そうでない場合は注意してください。TrueFalse

于 2015-05-06T07:46:38.127 に答える