Обработка входных данных в unittest, тест начинается, но больше ничего не происходит - PullRequest
0 голосов
/ 21 мая 2019

Мне нужно проверить функцию, которая обрабатывает ввод.Я новичок во всех юнит-тестах и ​​издевательствах, поэтому я просто следовал этому ответу https://stackoverflow.com/a/21047132/6531256, что он очень похож на мой случай.Ну, проблема в том, что когда я запускаю тест, кажется, что он запускается, а просто остается там и ничего не происходит.Мне нужно выйти с помощью ctrl-c, чтобы остановить его, затем я получаю трассировку, которая не очень помогает (по крайней мере, для меня).

Вот тестовый код:

import unittest
import unittest.mock
from unittest.mock import patch
from work1 import User

class TestWork1(unittest.TestCase, User):

    @patch('builtins.input', return_value= "36")
    def test_userNum(self,return_value):

        self.assertEqual(self.userNum(), "Invalid number. Put a 4-digit number:")


if __name__ == "__main__":
    unittest.main()

Вот функция, пытающаяся проверить:

class User():

    def userNum(self):

        self.user_num = int(input("Put a 4-digit number"))
        while len(str(self.user_num)) != 4:
            self.user_num = int(input("Invalid number. Put a 4-digit number:"))

Вот пример трассировки (всегда немного другой):

Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.5/unittest/__main__.py", line 18, in <module>
    main(module=None)
  File "/usr/lib/python3.5/unittest/main.py", line 94, in __init__
    self.runTests()
  File "/usr/lib/python3.5/unittest/main.py", line 255, in runTests
    self.result = testRunner.run(self.test)
  File "/usr/lib/python3.5/unittest/runner.py", line 176, in run
    test(result)
  File "/usr/lib/python3.5/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.5/unittest/suite.py", line 122, in run
    test(result)
  File "/usr/lib/python3.5/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.5/unittest/suite.py", line 122, in run
    test(result)
  File "/usr/lib/python3.5/unittest/suite.py", line 84, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.5/unittest/suite.py", line 122, in run
    test(result)
  File "/usr/lib/python3.5/unittest/case.py", line 648, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.5/unittest/case.py", line 600, in run
    testMethod()
  File "/usr/lib/python3.5/unittest/mock.py", line 1157, in patched
    return func(*args, **keywargs)
  File "/home/cristian/venvs/EB/test_work1.py", line 15, in test_userNum
    self.assertEqual(self.userNum(), "Invalid number. Put a 4-digit number:")
  File "/home/cristian/venvs/EB/work1.py", line 15, in userNum
    self.user_num = int(input("Invalid number. Put a 4-digit number:""))
  File "/usr/lib/python3.5/unittest/mock.py", line 916, in __call__
    _mock_self._mock_check_sig(*args, **kwargs)
KeyboardInterrupt

Что может быть не так?

1 Ответ

1 голос
/ 22 мая 2019

У вашего кода есть несколько проблем:

  1. Ваш цикл работает бесконечно, потому что вы исправляете builtin.input, чтобы всегда возвращать "36".Это не позволит циклу завершиться - когда вы запускаете код, кажется, что ничего не происходит, но код просто зацикливается.Чтобы увидеть, что происходит, вы можете поместить print() заявлений в интересные места.Чтобы исправить это, вы должны либо определить return_value так, чтобы он возвращал четырехзначное число, либо вы должны определить side_effect как список, подобный ["36", "1234"], чтобы последовательные вызовы builtin.input возвращали разные значения.Последний вариант показан в примере кода ниже.
  2. Ваше утверждение сравнивает результат self.userNum() со строкой.Но self.userNum() ничего не возвращает.Из вашего тестового кода кажется, что вы хотите проверить, что buitin.input был вызван с соответствующей строкой аргумента.Как это можно сделать, показано в коде ниже - как одно из возможных решений, где фактически проверяется вся последовательность вызовов builtin.input.Это только для демонстрации, а не для того, чтобы подразумевать, что это должно быть сделано таким образом.

Возможное решение:

import unittest
import unittest.mock
from unittest.mock import patch, call

class User():
    def userNum(self):
        self.user_num = int(input("Put a 4-digit number"))
        while len(str(self.user_num)) != 4:
            self.user_num = int(input("Invalid number. Put a 4-digit number:"))

class TestWork1(unittest.TestCase, User):
    @patch('builtins.input', side_effect=["36", "1234"])
    def test_userNum(self, input_mock):
        expected = [
            call('Put a 4-digit number'),
            call('Invalid number. Put a 4-digit number:')]
        self.userNum()
        self.assertEqual(input_mock.mock_calls, expected)

if __name__ == "__main__":
    unittest.main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...