Reputation: 470
I'm looking for any insight into why the below error is raised. I'm wondering if the issue is with pytest?
I'm otherwise using getpass with no issues in my application. However, I'm new to the testing world.
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")
Command line:
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 ================
Any input appreciated.
Now babbling in the hope that the system will grant me the ability to post and stop asking for more details. I have nothing more to add.
Upvotes: 0
Views: 5338
Reputation: 43
To work this I had to import getpass and use the method explicitly and then use a monkeypatch with an iterable.
common.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))
assert username_password() == ("Me", "xxx")
Upvotes: 3
Reputation: 94676
Fix: getpass
-> input
:
username = input("Username: ")
And patch input
instead of 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")
Upvotes: 1