10

I would like to know which testing tools for python support the testing of interactive programs. For example, I have an application launched by:

$ python dummy_program.py 

>> Hi whats your name? Joseph

I would like to instrument Joseph so I can emulate that interactive behaviour.

0

3 Answers 3

2

If you are testing an interactive program, consider using expect. It's designed specifically for interacting with console programs (though, more for automating tasks rather than testing).

If you don't like the language expect is based on (tcl) you can try pexpect which also makes it easy to interact with a console program.

Sign up to request clarification or add additional context in comments.

Comments

1

Your best bet is probably dependency injection, so that what you'd ordinarily pick up from sys.stdin (for example) is actually an object passed in. So you might do something like this:

import sys

def myapp(stdin, stdout):
    print >> stdout, "Hi, what's your name?"
    name = stdin.readline()
    print >> stdout "Hi,", name

# This might be in a separate test module
def test_myapp():
    mock_stdin = [create mock object that has .readline() method]
    mock_stdout = [create mock object that has .write() method]
    myapp(mock_stdin, mock_stdout)

if __name__ == '__main__':
    myapp(sys.stdin, sys.stdout)

Fortunately, Python makes this pretty easy. Here's a more detailed link for an example of mocking stdin: http://konryd.blogspot.com/2010/05/mockity-mock-mock-some-love-for-mock.html

1 Comment

Indeed, dependency injection is the way to go. Although, if for some strange reason he can't change the code, he could directly change stdin and stdout with sys.stdin = mock_stdin and sys.stdout = mock_stdout. If he needed the originals during the test, he could use sys.__stdin__ and sys.__stdout__, which keep the original values.
0

A good example might be the file test_embed.py of the IPython package.

There two different approaches are used:

subprocess

import subprocess
# ...
subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate(_exit_cmd_string)

pexpect (as already mentioned by Brian Oakley

import pexpect
# ...
child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor'],
                          env=env)
# ...
child.sendline("some_command")
child.expect(ipy_prompt)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.