Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于cmd模块编写python3shell单元测试_Python_Unit Testing_Python 3.x_Cmd_Python Unittest - Fatal编程技术网

基于cmd模块编写python3shell单元测试

基于cmd模块编写python3shell单元测试,python,unit-testing,python-3.x,cmd,python-unittest,Python,Unit Testing,Python 3.x,Cmd,Python Unittest,我正试图为我的项目编写一些单元测试,但在为cmd模块的功能编写单元测试时遇到了问题 我遵循这个问题的例子: 我们考虑如下: #!/usr/bin/env python3 import cmd import sys class Interpreter(cmd.Cmd): def __init__(self, stdin=sys.stdin, stdout=sys.stdout): cmd.Cmd.__init__(self, stdin=stdin, stdout=s

我正试图为我的项目编写一些单元测试,但在为cmd模块的功能编写单元测试时遇到了问题

我遵循这个问题的例子:

我们考虑如下:

#!/usr/bin/env python3

import cmd
import sys


class Interpreter(cmd.Cmd):
    def __init__(self, stdin=sys.stdin, stdout=sys.stdout):
        cmd.Cmd.__init__(self, stdin=stdin, stdout=stdout)

    def do_show(self, args):
        print("Hello world!")

if __name__ == "__main__":
    interpreter = Interpreter()
    interpreter.onecmd("show")
这是我的单元测试:

import unittest
import unittest.mock
import main
import sys


class CmdUiTest(unittest.TestCase):
    def setUp(self):
        self.mock_stdin = unittest.mock.create_autospec(sys.stdin)
        self.mock_stdout = unittest.mock.create_autospec(sys.stdout)

    def create(self):
        return main.Interpreter(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_show_command(self):
        cli = self.create()
        cli.onecmd("show")
        self.assertEqual("Hello world!", self._last_write(1))
如果我理解正确,在sys.stdin和sys.stdout的unittest mock中,通过方法_last_write(),我应该能够使用
self.mock_stdout.write.call_args_list[-:]

测试结果

/home/john/rextenv/bin/python3 /home/john/pycharm/helpers/pycharm/utrunner.py /home/john/PycharmProjects/stackquestion/tests/test_show.py::CmdUiTest::test_show_command true
Testing started at 20:55 ...
Hello world!

Process finished with exit code 0

Failure
Expected :'Hello world!'
Actual   :''
 <Click to see difference>

Traceback (most recent call last):
  File "/home/john/PycharmProjects/stackquestion/tests/test_show.py", line 25, in test_show_command
    self.assertEqual("Hello world!", self._last_write(1))
AssertionError: 'Hello world!' != ''
- Hello world!
+ 
/home/john/rextenv/bin/python3/home/john/pycharm/helpers/pycharm/utrunner.py/home/john/pycharm项目/stackquestion/tests/test_show.py::CmdUiTest::test_show_命令true
测试在20:55开始。。。
你好,世界!
进程已完成,退出代码为0
失败
期待:“你好,世界!”
实际值:“”
回溯(最近一次呼叫最后一次):
test_show_命令第25行的文件“/home/john/PycharmProjects/stackquestion/tests/test_show.py”
self.assertEqual(“你好,世界!”,self.\u最后一次写(1))
断言者错误:“你好,世界!”!=”
-你好,世界!
+ 
正如你所见,你好世界!从
do_show()
实际上打印到标准输出上。但由于某种原因,
self.mock\stdout.write.call\u args\u list
总是返回空列表

(顺便说一句,我正在从Pycharm运行测试,但我也尝试从shell执行它们,没有区别)

我所需要的只是能够以某种方式测试我的cmd解释器的功能。只需比较打印输出


我还试图模拟内置打印,但这更破坏了我的测试(实际的代码和测试更复杂)。但我不认为用()模拟打印和检查调用的_真的不是必要的或正确的解决方案。模拟stdout应该是可能的。

与orld有区别 不确定这是否是你想要的,最后一篇文章肯定不起作用

F
======================================================================
FAIL: test_show_command (__main__.CmdUiTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./int.py", line 32, in test_show_command
    self.assertEqual('Hello World!', fakeOutput.getvalue().strip())
AssertionError: 'Hello World!' != 'Hello world!'
- Hello World!
?       ^
+ Hello world!
?       ^


----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (failures=1)
更改为使用unitte.mock.patch-我的python版本是3.5

from unittest.mock import patch
from io import StringIO


    # not working for reasons unknown
    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:]))

    # modified with unittest.mock.patch
    def test_show_command(self):
        # Interpreter obj
        cli = self.create()
        with patch('sys.stdout', new=StringIO()) as fakeOutput:
            #print ('hello world')
            self.assertFalse(cli.onecmd('show'))
        self.assertEqual('Hello World!', fakeOutput.getvalue().strip())

会的,谢谢你。虽然很奇怪为什么最后一次写入()不起作用。当提供了stdout以外的内容时,cmd模块似乎完全跳过了.write()。可能是cmd模块中的bug。