How To Make Pytest Wait For (manual) User Action?
Solution 1:
So, I found a hint by a pytest dev, based on which I basically do what the capsys.disable()
function does:
@pytest.fixture(scope="module")defdisconnect_component(pytestconfig):
capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')
capmanager.suspend_global_capture(in_=True)
input('Disconnect component, then press enter')
capmanager.resume_global_capture()
yield# At this point all the tests with this fixture are run
capmanager.suspend_global_capture(in_=True)
input('Connect component again, then press enter')
capmanager.resume_global_capture()
This works flawlessly as far as I can see. Don't forget the in_=True
bit.
Edit: From pytest 3.3.0 (I think), capmanager.suspendcapture
and capmanager.resumecapture
were renamed to capmanager.suspend_global_capture
and capmanager.resume_global_capture
, respectively.
Solution 2:
As of pytest 5, as a fixture, you can use this:
@pytest.fixture
defsuspend_capture(pytestconfig):
classsuspend_guard:def__init__(self):
self.capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')
def__enter__(self):
self.capmanager.suspend_global_capture(in_=True)
def__exit__(self, _1, _2, _3):
self.capmanager.resume_global_capture()
yield suspend_guard()
Example usage:
deftest_input(suspend_capture):
with suspend_capture:
input("hello")
Solution 3:
Maybe it's worth noting that above solution doesn't have to be in a fixture. I've made a helper function for that:
import pytest
defask_user_input(msg=''):
""" Asks user to check something manually and answer a question
"""
notification = "\n\n???\tANSWER NEEDED\t???\n\n{}".format(msg)
# suspend input capture by py.test so user input can be recorded here
capture_manager = pytest.config.pluginmanager.getplugin('capturemanager')
capture_manager.suspendcapture(in_=True)
answer = raw_input(notification)
# resume capture after question have been asked
capture_manager.resumecapture()
logging.debug("Answer: {}".format(answer))
return answer
Solution 4:
For future reference, if you need to use input
with pytest
. You can do this in any part of your pytest, setup_class
, test_...
, teardown_method
, etc. This is for pytest > 3.3.x
import pytest
capture_manager = pytest.config.pluginmanager.getplugin('capturemanager')
capture_manager.suspend_global_capture(in_=True)
answer = input('My reference text here')
capture_manager.resume_global_capture()
Solution 5:
Solutions that use the global pytest.config
object no longer work. For my use case, using --capture=sys
together with a custom input()
that uses stdin
and stdout
directly works well.
deffd_input(prompt):
with os.fdopen(os.dup(1), "w") as stdout:
stdout.write("\n{}? ".format(prompt))
with os.fdopen(os.dup(2), "r") as stdin:
return stdin.readline()
Post a Comment for "How To Make Pytest Wait For (manual) User Action?"