Тестирование модуля getpass: "ввод пароля может быть повторен"

Я ищу любое понимание того, почему возникает ошибка ниже. Мне интересно, если проблема с pytest?

В противном случае я использую getpass без проблем в моем приложении. Тем не менее, я новичок в мире тестирования.

common.py:

def username_password():
    """Get login credentials"""
    # show current windows user
    print("\nThe current windows user is {}\n".format(getuser()))

    username = getpass("Username: ")
    password = getpass("Password: ")
    return username, password

test_common.py:

from unittest.mock import patch
from common import username_password

@patch("getpass.getpass")
@patch("getpass.getuser")
def test_username_password(getuser, getpass):
    getuser.return_value = "Me"
    getpass.return_value = "xxx"
    assert username_password() == ("Me", "xxx")

Командная строка:

py.test test_common.py --cov  --cov-report term-missing
============================= test session starts =============================
platform win32 -- Python 3.5.2, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: C:\Users\JB\Desktop\Coding\Bot\Bot_tests, inifile:
plugins: cov-2.5.1
collected 17 items

test_common.py ....F..x.........

================================== FAILURES ===================================
___________________________ test_username_password ____________________________

getuser = <MagicMock name='getuser' id='1759491735280'>
getpass = <MagicMock name='getpass' id='1759491732424'>

    @patch("getpass.getpass")
    @patch("getpass.getuser")
    def test_username_password(getuser, getpass):
        getuser.return_value = "Me"
        getpass.return_value = "xxx"
>       u, p = username_password()

test_common.py:65:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\Bot\common.py:29: in username_password
    username = getpass("Username: ")
..\..\environments\ipython_env\Anaconda3\lib\getpass.py:101: in win_getpass
    return fallback_getpass(prompt, stream)
..\..\environments\ipython_env\Anaconda3\lib\getpass.py:127: in fallback_getpass
    return _raw_input(prompt, stream)
..\..\environments\ipython_env\Anaconda3\lib\getpass.py:147: in _raw_input
    line = input.readline()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <_pytest.capture.DontReadFromInput object at 0x00000199A8BD37F0>
args = ()

    def read(self, *args):
>       raise IOError("reading from stdin while output is captured")
E       OSError: reading from stdin while output is captured

..\..\environments\ipython_env\Anaconda3\lib\site-packages\_pytest\capture.py:433: OSError
---------------------------- Captured stdout call -----------------------------

The current windows user is JB

---------------------------- Captured stderr call -----------------------------
C:\Users\JB\Desktop\Coding\environments\ipython_env\Anaconda3\lib\getpass.py:101: GetPassWarning: Can not control echo on the terminal.
  return fallback_getpass(prompt, stream)
Warning: Password input may be echoed.
Username:
=============== 1 failed, 15 passed, 1 xfailed in 0.50 seconds ================

Любой вклад приветствуется.

Теперь болтаю в надежде, что система предоставит мне возможность публиковать и перестать спрашивать более подробную информацию. Мне больше нечего добавить.

2 ответа

Для этого мне пришлось импортировать getpass и явно использовать этот метод, а затем использовать обезьяний патч с итерируемым объектом.

общий.py

      import getpass

def username_password():
"""Get login credentials"""
    # show current windows user
    print("\nThe current windows user is {}\n".format(getuser()))

    username = getpass.getpass("Username: ")
    password = getpass.getpass("Password: ")
    return username, password

test_common.py

      from common import username_password

def test_username_password(monkeypatch):
    responses = iter(['Me', 'xxx'])
    monkeypatch.setattr('getpass.getpass', lambda _: next(responses))    
    u, p = username_password()
    assert u == "Me"
    assert p == "xxx"

Fix: getpass -> input:

username = input("Username: ")

И патч input вместо getpass:

common.py:

def username_password():
    """Get login credentials"""
    # show current windows user
    print("\nThe current windows user is {}\n".format(getuser()))

    username = input("Username: ")
    password = getpass("Password: ")
    return username, password

test_common.py:

from unittest.mock import patch
from common import username_password

@patch("builtins.input")
@patch("getpass.getpass")
def test_username_password(input, getpass):
    input.return_value = "Me"
    getpass.return_value = "xxx"
    assert username_password() == ("Me", "xxx")
Другие вопросы по тегам