Я пытаюсь написать некоторые unittests для моего проекта, но у меня возникают проблемы с написанием unittests для функциональности из модуля cmd.Написание unittest для оболочки python3 на основе модуля cmd
Я последовал примеру от этого вопроса: Create automated tests for interactive shell based on Python's cmd module
Рассмотрим следующее:
#!/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")
И это мой UnitTest:
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))
Если я понимаю правильно, в UnitTest издеваться из создаются sys.stdin и sys.stdout, а с помощью метода _last_write() я должен иметь доступ к списку аргументов, которые были написаны на насмешливый stdout нас ING self.mock_stdout.write.call_args_list[-nr:]
Результат теста
/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!
+
Как вы можете видеть Привет, мир! от do_show()
фактически печатается на стандартный вывод. Но по какой-то причине self.mock_stdout.write.call_args_list
всегда возвращает пустой список.
(Btw. Я бегу тесты от PyCharm, но я также пытался их выполнение из оболочки, без разницы)
Все, что мне нужно, чтобы быть в состоянии как-то тест функциональность моего CMD переводчика. Просто сравните выходные данные.
Я также попытался высмеять встроенный отпечаток, но это еще больше нарушило мой тест (более сложный код и тест). Но я не считаю, что насмешливая печать и проверка named_with() действительно не нужны или правильное решение. Издевательская stdout должна быть возможной.
Сойдет спасибо. Хотя странно, почему _last_write() не работает. Кажется, модуль cmd пропускает .write() вообще, когда поставляется что-то еще, чем stdout. Вероятно, ошибка в модуле cmd. – J91321