Python 3 unittest simulates user input
How can I simulate user input in the middle of a function called by unit test (using Python 3 unittest)? For example, I have a function foo()
that I am testing. In a function, foo()
it asks for user input:
x = input(msg)
And the output is based on the input:
print("input: {0}".format(x))
I would like my unit test to run foo()
, inject input, and compare the output to the expected output.
source to share
I have this problem regularly when I try to test the code that brings up dialogs for user input and the same solution should work for both. You need to provide a new function associated with a name input
in your test scope with the same signature as the standard function input
, which simply returns a test value without actually asking the user. Depending on how your tests and code are set up, this injection can be done in several ways, so I'll leave it as an exercise for the reader, but your replacement method will be as simple as this:
def my_test_input(message):
return 7
Obviously, you could also include content message
, if relevant, and return a data type of your choice. You can also do something more flexible and general, which allows you to reuse the same replacement method in multiple situations:
def my_test_input(retval, message):
return retval
and then you add the partial function to input
:
import functools
test_input_a = functools.partial(my_test_input, retval=7)
test_input_b = functools.partial(my_test_input, retval="Foo")
We test_input_a
also leave test_input_b
as functions that take one argument message
, with an already bound argument retval
.
source to share
Having difficulty testing certain components due to dependencies is usually a sign of poor design. Your function foo
should not depend on a global function input
, but rather on a parameter. Then, when you run the program in a production environment, you bundle things up so that the invoked foo
with the return result input
. Therefore, you foo
should read:
def foo(input):
# do something with input
This will make testing easier. And by the way, if your tests have dependencies IO
, they are no longer modular, but rather functional. Check out the Misko Hevery Blog to learn more about testing.
source to share