[Tutor] how to unittest cli input
Alex Kleider
akleider at sonic.net
Sun Oct 11 18:29:56 CEST 2015
On 2015-10-10 18:10, Cameron Simpson wrote:
On 10Oct2015 17:41, Alex Kleider <akleider at sonic.net> wrote:
I'm tOn 2015-10-10 18:10, Cameron Simpson wrote:
On 10Oct2015 17:41, Alex Kleider <akleider at sonic.net> wrote:
I'm trying to follow a test driven development paradigm (using
unittest) but can't figure out how to test functions that
collect
info from the command line such as the following.
Aside: I'd say "the standard input" , not "the command line"; to me
the latter connotes to command line arguments fro sys.argv.
Point well taken! stdin it is. Ben suggested I should have used the
term "interactive" which certainly fits well.
Anyway, ...
..................
However, you'r eusing input(), which unconditionally uses stdin and
stdout. In that circumstance I'd consider this:
def collect_data(src=None, out=None):
if src is None:
src = sys.stdin
if out is None:
out = sys.stdout
ostdin = sys.stdin
sys.stdin = src
ostdout = sys.stdout
sys.stdout = out
ret = {}
ret['first'] = input("Enter your first name: ")
... etc ...
sys.stdout = ostdout
sys.stdin = ostdin
Note that this is not thread safe because sys.stdin is a global, but
it should work for testing.
Anyway, perhap that gives you some way forward.
Yes indeed, and thank you for your input.
Here's where I'm going with your suggestion:
# collect.py
test_data = 'test_src.txt'
def data_collection_wrapper(collect, source=None):
"""
"""
if source:
ostdin = sys.stdin
ostdout = sys.stdout
src = open(source, 'r')
sys.stdin = src
out = open('/dev/null', 'w') # Dump the prompts.
sys.stdout = out
ret = collect()
if source:
src.close()
out.close()
sys.stdin = ostdin
sys.stdout = ostdout
return ret
def collect_data():
ret = {}
ret['first'] = input("Enter your first name: ")
ret['last'] = input("Enter your last name: ")
ret['phone'] = input("Your mobile phone #: ")
return ret
def main():
print(collect_data()) # < check that user input works
# then check that can test can be automated >
print(data_collection_wrapper(collect_data,
src=test_data))
if __name__ == "__main__":
main()
Perhaps data_collection_wrapper could be made into a decorator (about
which I am still pretty naive.)
It'll take more studying on my part before I'll be able to implement
Ben's suggestion.
Alex
ps I was tempted to change the "Subject:" to remove 'cli' and replace it
with 'interactive' but remember many admonitions to not do that so have
left it as is.
More information about the Tutor
mailing list