Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #68150 > unrolled thread

Testing interactive code using raw_input

Started bySteven D'Aprano <steve+comp.lang.python@pearwood.info>
First post2014-03-10 15:59 +0000
Last post2014-03-11 10:39 +1100
Articles 7 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  Testing interactive code using raw_input Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-10 15:59 +0000
    Re: Testing interactive code using raw_input Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2014-03-10 16:05 +0000
    Re:Testing interactive code using raw_input Dave Angel <davea@davea.name> - 2014-03-10 12:40 -0400
    Re: Testing interactive code using raw_input Peter Otten <__peter__@web.de> - 2014-03-10 17:57 +0100
      Re: Testing interactive code using raw_input Steven D'Aprano <steve@pearwood.info> - 2014-03-11 08:26 +0000
    Re: Testing interactive code using raw_input Ethan Furman <ethan@stoneleaf.us> - 2014-03-10 09:53 -0700
    Re: Testing interactive code using raw_input Ben Finney <ben+python@benfinney.id.au> - 2014-03-11 10:39 +1100

#68150 — Testing interactive code using raw_input

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-03-10 15:59 +0000
SubjectTesting interactive code using raw_input
Message-ID<531de147$0$29994$c3e8da3$5496439d@news.astraweb.com>
Does anyone have any good hints for testing interactive code that uses 
raw_input, or input in Python 3?

A simple technique would be to factor out the interactive part, e.g. like 
this:

# Before
def spam():
    answer = raw_input(prompt)
    return eggs(answer) + cheese(answer) + toast(answer)

# After
def spam():
    answer = raw_input(prompt)
    return func(answer)

def func(s):
    return eggs(s) + cheese(s) + toast(s)



and then test func. But how about times where it is inconvenient to 
factor out the raw_input stuff out of the function? E.g. suppose you have 
a function that takes some arguments, gathers some more values 
interactively, processes the lot, and then returns a result. With an 
automated test, I can provide the arguments, and check the result, but 
what are my options for *automatically* supplying input to raw_input?



-- 
Steven

[toc] | [next] | [standalone]


#68153

FromOscar Benjamin <oscar.j.benjamin@gmail.com>
Date2014-03-10 16:05 +0000
Message-ID<mailman.8005.1394467535.18130.python-list@python.org>
In reply to#68150
On 10 March 2014 15:59, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> Does anyone have any good hints for testing interactive code that uses
> raw_input, or input in Python 3?
>
> A simple technique would be to factor out the interactive part, e.g. like
> this:
>
> # Before
> def spam():
>     answer = raw_input(prompt)
>     return eggs(answer) + cheese(answer) + toast(answer)
>
> # After
> def spam():
>     answer = raw_input(prompt)
>     return func(answer)
>
> def func(s):
>     return eggs(s) + cheese(s) + toast(s)
>
>
>
> and then test func. But how about times where it is inconvenient to
> factor out the raw_input stuff out of the function? E.g. suppose you have
> a function that takes some arguments, gathers some more values
> interactively, processes the lot, and then returns a result. With an
> automated test, I can provide the arguments, and check the result, but
> what are my options for *automatically* supplying input to raw_input?

Use a subprocess?


Oscar

[toc] | [prev] | [next] | [standalone]


#68160

FromDave Angel <davea@davea.name>
Date2014-03-10 12:40 -0400
Message-ID<mailman.8010.1394469366.18130.python-list@python.org>
In reply to#68150
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> Wrote in
 message:
> Does anyone have any good hints for testing interactive code that uses 
> raw_input, or input in Python 3?
> 
> A simple technique would be to factor out the interactive part, e.g. like 
> this:
> 
> # Before
> def spam():
>     answer = raw_input(prompt)
>     return eggs(answer) + cheese(answer) + toast(answer)
> 
> # After
> def spam():
>     answer = raw_input(prompt)
>     return func(answer)
> 
> def func(s):
>     return eggs(s) + cheese(s) + toast(s)
> 
> 
> 
> and then test func. But how about times where it is inconvenient to 
> factor out the raw_input stuff out of the function? E.g. suppose you have 
> a function that takes some arguments, gathers some more values 
> interactively, processes the lot, and then returns a result. With an 
> automated test, I can provide the arguments, and check the result, but 
> what are my options for *automatically* supplying input to raw_input?
> 

How about reassigning sys.stdin to a StringIO buffer?

-- 
DaveA

[toc] | [prev] | [next] | [standalone]


#68162

FromPeter Otten <__peter__@web.de>
Date2014-03-10 17:57 +0100
Message-ID<mailman.8012.1394470659.18130.python-list@python.org>
In reply to#68150
Steven D'Aprano wrote:

> Does anyone have any good hints for testing interactive code that uses
> raw_input, or input in Python 3?
> 
> A simple technique would be to factor out the interactive part, e.g. like
> this:
> 
> # Before
> def spam():
>     answer = raw_input(prompt)
>     return eggs(answer) + cheese(answer) + toast(answer)
> 
> # After
> def spam():
>     answer = raw_input(prompt)
>     return func(answer)
> 
> def func(s):
>     return eggs(s) + cheese(s) + toast(s)
> 
> 
> 
> and then test func. But how about times where it is inconvenient to
> factor out the raw_input stuff out of the function? E.g. suppose you have
> a function that takes some arguments, gathers some more values
> interactively, processes the lot, and then returns a result. With an
> automated test, I can provide the arguments, and check the result, but
> what are my options for *automatically* supplying input to raw_input?

https://pypi.python.org/pypi/mock

In Python 3 this is part of the standard library:

from unittest import mock

def sum_it():
    return "{} + {} = {}".format(input(), input(), input())

with mock.patch('builtins.input', side_effect="123"):
    assert sum_it() == "1 + 2 = 3"

I have not yet used it myself so far; instead I did something like

def sum_it(input=input):
   ...

and then passed a hand-crafted mock input function to increase coverage.

[toc] | [prev] | [next] | [standalone]


#68204

FromSteven D'Aprano <steve@pearwood.info>
Date2014-03-11 08:26 +0000
Message-ID<531ec898$0$2923$c3e8da3$76491128@news.astraweb.com>
In reply to#68162
On Mon, 10 Mar 2014 17:57:19 +0100, Peter Otten wrote:

> Steven D'Aprano wrote:

>> what are my options for *automatically* supplying input to raw_input?
> 
> https://pypi.python.org/pypi/mock
> 
> In Python 3 this is part of the standard library:

Nice!


Thanks to everyone who responded.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#68168

FromEthan Furman <ethan@stoneleaf.us>
Date2014-03-10 09:53 -0700
Message-ID<mailman.8015.1394473687.18130.python-list@python.org>
In reply to#68150
On 03/10/2014 08:59 AM, Steven D'Aprano wrote:
> With an
> automated test, I can provide the arguments, and check the result, but
> what are my options for *automatically* supplying input to raw_input?

pexpect?

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


#68182

FromBen Finney <ben+python@benfinney.id.au>
Date2014-03-11 10:39 +1100
Message-ID<mailman.8027.1394494787.18130.python-list@python.org>
In reply to#68150
Steven D'Aprano <steve+comp.lang.python@pearwood.info> writes:

> Does anyone have any good hints for testing interactive code that uses 
> raw_input, or input in Python 3?

Are you testing the behaviour of the ‘input’ function?

If not, then it is an external dependency; and, since you're not
interested in testing its behaviour, you can contrive its behaviour to
be exactly what you want: Mock the function during your unit test, and
get it to produce whatever output you like.

Mocking is a blunt instrument, but when the external dependency is
problematic – and it seems like “access to an interactive terminal” is a
problematic dependency – you should mock the dependency out for those
tests where the dependency is external to what you want to test.

-- 
 \           “'Tis strange, — but true; for truth is always strange; / |
  `\    Stranger than fiction.” —“Lord” George Gordon Noel Byron, _Don |
_o__)                                                            Juan_ |
Ben Finney

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web